sigh 0.3.5 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/bin/sigh +12 -46
- data/lib/sigh.rb +5 -0
- data/lib/sigh/developer_center.rb +38 -34
- data/lib/sigh/developer_center_signing.rb +5 -5
- data/lib/sigh/options.rb +74 -0
- data/lib/sigh/profile_analyser.rb +1 -1
- data/lib/sigh/resign.rb +64 -32
- data/lib/sigh/version.rb +1 -1
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f526a0a5cfb3f72abca695aa7345504a520539f
|
4
|
+
data.tar.gz: 2d750cc363d9776803b4235217727a16a48821ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73a2d366758dc8eb917a751e0250a5286f1acb89ae3626eb79cfb2f7482916acdaea88d89f01590b354fa1d328f2bb1c21e105db33dd941a68f3984145ec1d7f
|
7
|
+
data.tar.gz: 6fddc9be1d9c09abb57764a6fb75a6226a3027f984ab7141ffe42d4d834eddddc33dc7a21704510b68694a53725e388d1586ba55ea6c41e56d4efb27a9fdb7e8
|
data/README.md
CHANGED
@@ -47,7 +47,7 @@ Get in contact with the developer on Twitter: [@KrauseFx](https://twitter.com/Kr
|
|
47
47
|
|
48
48
|
-------
|
49
49
|
|
50
|
-
<h5 align="center"><code>sigh</code> is part of <a href="
|
50
|
+
<h5 align="center"><code>sigh</code> is part of <a href="https://fastlane.tools">fastlane</a>: connect all deployment tools into one streamlined workflow.</h5>
|
51
51
|
|
52
52
|
|
53
53
|
# Features
|
@@ -169,9 +169,9 @@ If you're using [cert](https://github.com/KrauseFx/cert) in combination with [fa
|
|
169
169
|
```sigh``` uses the [password manager](https://github.com/KrauseFx/CredentialsManager) from `fastlane`. Take a look the [CredentialsManager README](https://github.com/KrauseFx/CredentialsManager) for more information.
|
170
170
|
|
171
171
|
# Tips
|
172
|
-
## [`fastlane`](
|
172
|
+
## [`fastlane`](https://fastlane.tools) Toolchain
|
173
173
|
|
174
|
-
- [`fastlane`](
|
174
|
+
- [`fastlane`](https://fastlane.tools): Connect all deployment tools into one streamlined workflow
|
175
175
|
- [`deliver`](https://github.com/KrauseFx/deliver): Upload screenshots, metadata and your app to the App Store using a single command
|
176
176
|
- [`snapshot`](https://github.com/KrauseFx/snapshot): Automate taking localized screenshots of your iOS app on every device
|
177
177
|
- [`frameit`](https://github.com/KrauseFx/frameit): Quickly put your screenshots into the right device frames
|
data/bin/sigh
CHANGED
@@ -6,6 +6,7 @@ require 'sigh'
|
|
6
6
|
require 'commander'
|
7
7
|
require 'credentials_manager/password_manager'
|
8
8
|
require 'credentials_manager/appfile_config'
|
9
|
+
require 'sigh/options'
|
9
10
|
|
10
11
|
HighLine.track_eof = false
|
11
12
|
|
@@ -16,53 +17,33 @@ class SighApplication
|
|
16
17
|
program :version, Sigh::VERSION
|
17
18
|
program :description, 'CLI for \'sigh\' - Because you would rather spend your time building stuff than fighting provisioning'
|
18
19
|
program :help, 'Author', 'Felix Krause <sigh@krausefx.com>'
|
19
|
-
program :help, 'Website', '
|
20
|
+
program :help, 'Website', 'https://fastlane.tools'
|
20
21
|
program :help, 'GitHub', 'https://github.com/krausefx/sigh'
|
21
22
|
program :help_formatter, :compact
|
22
23
|
|
23
24
|
always_trace!
|
24
25
|
|
25
|
-
|
26
|
-
global_option '--skip_install', 'By default, the certificate will be added on your local machine. Setting this flag will skip this action.'
|
27
|
-
global_option '--development', 'Renew the development certificate instead of the production one.'
|
28
|
-
global_option '--force', 'Renew non-development provisioning profiles regardless of state.'
|
29
|
-
|
30
|
-
global_option '-a', '--identifier STRING', String, 'The bundle identifier of your app.'
|
31
|
-
global_option '-u', '--username STRING', String, 'Your Apple ID username.'
|
32
|
-
global_option '-n', '--cert_name STRING', String, 'The name of the generated certificate file.'
|
33
|
-
global_option '-o', '--output STRING', String, 'The folder in which the file should be generated.'
|
34
|
-
global_option '-d', '--cert_date STRING', String, 'The certificate with the given expiry date used to renew. (e.g. "Nov 11, 2017")'
|
35
|
-
global_option '-c', '--cert_owner STRING', String, 'The certificate name to use for new profiles, or to renew with. (e.g. "Felix Krause")'
|
36
|
-
global_option '-f', '--filename STRING', String, 'Filename to use for the provisioning profile'
|
26
|
+
FastlaneCore::CommanderGenerator.new.generate(Sigh::Options.available_options)
|
37
27
|
|
38
28
|
command :renew do |c|
|
39
29
|
c.syntax = 'sigh renew'
|
40
30
|
c.description = 'Renews the certificate (in case it expired) and outputs the path to the generated file'
|
41
31
|
|
42
32
|
c.action do |args, options|
|
43
|
-
|
44
|
-
username(options)
|
45
|
-
|
46
|
-
type = FastlaneCore::DeveloperCenter::APPSTORE
|
47
|
-
type = FastlaneCore::DeveloperCenter::ADHOC if options.adhoc
|
48
|
-
type = FastlaneCore::DeveloperCenter::DEVELOPMENT if options.development
|
33
|
+
Sigh.config = FastlaneCore::Configuration.create(Sigh::Options.available_options, options.__hash__)
|
49
34
|
|
50
|
-
|
51
|
-
ENV['SIGH_CERTIFICATE_EXPIRE_DATE'] = options.cert_date if options.cert_date
|
52
|
-
|
53
|
-
path = FastlaneCore::DeveloperCenter.new.run(app, type, options.cert_name, options.force)
|
35
|
+
path = Sigh::DeveloperCenter.new.run
|
54
36
|
|
55
37
|
if path
|
56
|
-
|
57
|
-
|
58
|
-
file_name = File.basename(path)
|
38
|
+
if Sigh.config[:filename]
|
39
|
+
file_name = Sigh.config[:filename]
|
59
40
|
else
|
60
|
-
file_name =
|
41
|
+
file_name = File.basename(path)
|
61
42
|
end
|
62
|
-
|
63
|
-
output = File.join(output_path.gsub("~", ENV["HOME"]), file_name)
|
64
|
-
FileUtils.mv(path, output)
|
65
|
-
system("open -g '#{output}'") unless
|
43
|
+
|
44
|
+
output = File.join(Sigh.config[:output_path].gsub("~", ENV["HOME"]), file_name)
|
45
|
+
(FileUtils.mv(path, output) rescue nil) # in case it already exists
|
46
|
+
system("open -g '#{output}'") unless Sigh.config[:skip_install]
|
66
47
|
puts output.green
|
67
48
|
end
|
68
49
|
end
|
@@ -84,21 +65,6 @@ class SighApplication
|
|
84
65
|
run!
|
85
66
|
end
|
86
67
|
|
87
|
-
def username(options)
|
88
|
-
user = options.username
|
89
|
-
user ||= ENV["SIGH_USERNAME"]
|
90
|
-
user ||= CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
|
91
|
-
|
92
|
-
CredentialsManager::PasswordManager.shared_manager(user) if user
|
93
|
-
end
|
94
|
-
|
95
|
-
def app_identifier(options)
|
96
|
-
value = options.identifier
|
97
|
-
value ||= ENV["SIGH_APP_IDENTIFIER"]
|
98
|
-
value ||= CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)
|
99
|
-
value ||= ask("App Identifier (Bundle ID, e.g. com.krausefx.app): ")
|
100
|
-
return value
|
101
|
-
end
|
102
68
|
end
|
103
69
|
|
104
70
|
SighApplication.new.run
|
data/lib/sigh.rb
CHANGED
@@ -6,6 +6,11 @@ require 'sigh/resign'
|
|
6
6
|
require 'fastlane_core'
|
7
7
|
|
8
8
|
module Sigh
|
9
|
+
# Use this to just setup the configuration attribute and set it later somewhere else
|
10
|
+
class << self
|
11
|
+
attr_accessor :config
|
12
|
+
end
|
13
|
+
|
9
14
|
Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
|
10
15
|
|
11
16
|
ENV['FASTLANE_TEAM_ID'] ||= ENV["SIGH_TEAM_ID"]
|
@@ -1,28 +1,30 @@
|
|
1
1
|
require 'fastlane_core/developer_center/developer_center'
|
2
2
|
require 'sigh/developer_center_signing'
|
3
3
|
|
4
|
-
module
|
5
|
-
class DeveloperCenter
|
4
|
+
module Sigh
|
5
|
+
class DeveloperCenter < FastlaneCore::DeveloperCenter
|
6
6
|
# Types of certificates
|
7
7
|
APPSTORE = "AppStore"
|
8
8
|
ADHOC = "AdHoc"
|
9
9
|
DEVELOPMENT = "Development"
|
10
10
|
|
11
11
|
PROFILES_URL_DEV = "https://developer.apple.com/account/ios/profile/profileList.action?type=limited"
|
12
|
-
|
13
12
|
|
14
|
-
def run
|
15
|
-
|
13
|
+
def run
|
14
|
+
@type = Sigh::DeveloperCenter::APPSTORE
|
15
|
+
@type = Sigh::DeveloperCenter::ADHOC if Sigh.config[:adhoc]
|
16
|
+
@type = Sigh::DeveloperCenter::DEVELOPMENT if Sigh.config[:development]
|
17
|
+
|
18
|
+
cert = maintain_app_certificate # create/download the certificate
|
16
19
|
|
17
|
-
type_name = type
|
18
|
-
|
19
|
-
cert_name ||= "#{type_name}_#{app_identifier}.mobileprovision" # default name
|
20
|
+
type_name = "Distribution" if @type == APPSTORE # both enterprise and App Store
|
21
|
+
cert_name ||= "#{type_name}_#{Sigh.config[:app_identifier]}.mobileprovision" # default name
|
20
22
|
cert_name += '.mobileprovision' unless cert_name.include?'mobileprovision'
|
21
23
|
|
22
24
|
output_path = File.join(TMP_FOLDER, cert_name)
|
23
25
|
File.write(output_path, cert)
|
24
26
|
|
25
|
-
store_provisioning_id_in_environment(output_path)
|
27
|
+
store_provisioning_id_in_environment(output_path)
|
26
28
|
|
27
29
|
return output_path
|
28
30
|
end
|
@@ -33,9 +35,10 @@ module FastlaneCore
|
|
33
35
|
ENV["SIGH_UDID"] = udid if udid
|
34
36
|
end
|
35
37
|
|
36
|
-
def maintain_app_certificate(
|
38
|
+
def maintain_app_certificate(force = nil)
|
39
|
+
force = Sigh.config[:force] if (force == nil)
|
37
40
|
begin
|
38
|
-
if type == DEVELOPMENT
|
41
|
+
if @type == DEVELOPMENT
|
39
42
|
visit PROFILES_URL_DEV
|
40
43
|
else
|
41
44
|
visit PROFILES_URL
|
@@ -48,29 +51,29 @@ module FastlaneCore
|
|
48
51
|
certs = post_ajax(@list_certs_url)
|
49
52
|
|
50
53
|
Helper.log.info "Checking if profile is available. (#{certs['provisioningProfiles'].count} profiles found)"
|
51
|
-
required_cert_types = type == DEVELOPMENT ? ['iOS Development'] : ['iOS Distribution', 'iOS UniversalDistribution']
|
54
|
+
required_cert_types = (@type == DEVELOPMENT ? ['iOS Development'] : ['iOS Distribution', 'iOS UniversalDistribution'])
|
52
55
|
certs['provisioningProfiles'].each do |current_cert|
|
53
56
|
next unless required_cert_types.include?(current_cert['type'])
|
54
57
|
|
55
58
|
details = profile_details(current_cert['provisioningProfileId'])
|
56
59
|
|
57
|
-
if details['provisioningProfile']['appId']['identifier'] == app_identifier
|
60
|
+
if details['provisioningProfile']['appId']['identifier'] == Sigh.config[:app_identifier]
|
58
61
|
# that's an Ad Hoc profile. I didn't find a better way to detect if it's one ... skipping it
|
59
|
-
next if type == APPSTORE && details['provisioningProfile']['deviceCount'] > 0
|
62
|
+
next if @type == APPSTORE && details['provisioningProfile']['deviceCount'] > 0
|
60
63
|
|
61
64
|
# that's an App Store profile ... skipping it
|
62
|
-
next if type != APPSTORE && details['provisioningProfile']['deviceCount'] == 0
|
65
|
+
next if @type != APPSTORE && details['provisioningProfile']['deviceCount'] == 0
|
63
66
|
|
64
67
|
# We found the correct certificate
|
65
|
-
if force && type != DEVELOPMENT
|
68
|
+
if force && @type != DEVELOPMENT
|
66
69
|
provisioningProfileId = current_cert['provisioningProfileId']
|
67
|
-
renew_profile(provisioningProfileId
|
68
|
-
return maintain_app_certificate(
|
70
|
+
renew_profile(provisioningProfileId) # This one needs to be forcefully renewed
|
71
|
+
return maintain_app_certificate(false) # recursive
|
69
72
|
elsif current_cert['status'] == 'Active'
|
70
73
|
return download_profile(details['provisioningProfile']['provisioningProfileId']) # this one is already finished. Just download it.
|
71
74
|
elsif ['Expired', 'Invalid'].include? current_cert['status']
|
72
|
-
renew_profile(current_cert['provisioningProfileId']
|
73
|
-
return maintain_app_certificate(
|
75
|
+
renew_profile(current_cert['provisioningProfileId']) # This one needs to be renewed
|
76
|
+
return maintain_app_certificate(false) # recursive
|
74
77
|
end
|
75
78
|
|
76
79
|
break
|
@@ -79,18 +82,19 @@ module FastlaneCore
|
|
79
82
|
|
80
83
|
Helper.log.info "Could not find existing profile. Trying to create a new one."
|
81
84
|
# Certificate does not exist yet, we need to create a new one
|
82
|
-
create_profile
|
85
|
+
create_profile
|
83
86
|
# After creating the profile, we need to download it
|
84
|
-
return maintain_app_certificate(
|
87
|
+
return maintain_app_certificate(false) # recursive
|
85
88
|
|
86
89
|
rescue => ex
|
87
90
|
error_occured(ex)
|
88
91
|
end
|
89
92
|
end
|
90
93
|
|
91
|
-
def create_profile
|
92
|
-
|
93
|
-
|
94
|
+
def create_profile
|
95
|
+
app_identifier = Sigh.config[:app_identifier]
|
96
|
+
Helper.log.info "Creating new profile for app '#{app_identifier}' for type '#{@type}'.".yellow
|
97
|
+
certificates = code_signing_certificates(@type)
|
94
98
|
|
95
99
|
create_url = "https://developer.apple.com/account/ios/profile/profileCreate.action"
|
96
100
|
visit create_url
|
@@ -106,8 +110,8 @@ module FastlaneCore
|
|
106
110
|
end
|
107
111
|
|
108
112
|
value = enterprise ? 'inhouse' : 'store'
|
109
|
-
value = 'limited' if type == DEVELOPMENT
|
110
|
-
value = 'adhoc' if type == ADHOC
|
113
|
+
value = 'limited' if @type == DEVELOPMENT
|
114
|
+
value = 'adhoc' if @type == ADHOC
|
111
115
|
|
112
116
|
first(:xpath, "//input[@type='radio' and @value='#{value}']").click
|
113
117
|
click_next
|
@@ -137,7 +141,7 @@ module FastlaneCore
|
|
137
141
|
clicked = false
|
138
142
|
certificates.each do |cert|
|
139
143
|
cert_id = cert['certificateId']
|
140
|
-
input = if type == DEVELOPMENT
|
144
|
+
input = if @type == DEVELOPMENT
|
141
145
|
# development uses a checkbox and has no [] around the value
|
142
146
|
first(:xpath, "//input[@type='checkbox' and @value='#{cert_id}']")
|
143
147
|
else
|
@@ -156,7 +160,7 @@ module FastlaneCore
|
|
156
160
|
end
|
157
161
|
click_next
|
158
162
|
|
159
|
-
if type != APPSTORE
|
163
|
+
if @type != APPSTORE
|
160
164
|
# 4) Devices selection
|
161
165
|
wait_for_elements('.selectAll.column')
|
162
166
|
sleep 3
|
@@ -167,15 +171,15 @@ module FastlaneCore
|
|
167
171
|
|
168
172
|
# 5) Choose a profile name
|
169
173
|
wait_for_elements('.distributionType')
|
170
|
-
profile_name =
|
171
|
-
profile_name ||= [app_identifier, type].join(' ')
|
174
|
+
profile_name = Sigh.config[:provisioning_file_name]
|
175
|
+
profile_name ||= [app_identifier, @type].join(' ')
|
172
176
|
fill_in "provisioningProfileName", with: profile_name
|
173
177
|
click_next
|
174
178
|
wait_for_elements('.row-details')
|
175
179
|
end
|
176
180
|
|
177
|
-
def renew_profile(profile_id
|
178
|
-
certificate = code_signing_certificates(type).first
|
181
|
+
def renew_profile(profile_id)
|
182
|
+
certificate = code_signing_certificates(@type).first
|
179
183
|
|
180
184
|
details_url = "https://developer.apple.com/account/ios/profile/profileEdit.action?type=&provisioningProfileId=#{profile_id}"
|
181
185
|
Helper.log.info "Renewing provisioning profile '#{profile_id}' using URL '#{details_url}'"
|
@@ -188,7 +192,7 @@ module FastlaneCore
|
|
188
192
|
if certs.count == 1
|
189
193
|
certs.first.click
|
190
194
|
|
191
|
-
if type != APPSTORE
|
195
|
+
if @type != APPSTORE
|
192
196
|
# Add all devices
|
193
197
|
wait_for_elements('.selectAll.column')
|
194
198
|
sleep 3
|
@@ -1,5 +1,5 @@
|
|
1
|
-
module
|
2
|
-
class DeveloperCenter
|
1
|
+
module Sigh
|
2
|
+
class DeveloperCenter < FastlaneCore::DeveloperCenter
|
3
3
|
# Returns a array of hashes, that contains information about the iOS certificate
|
4
4
|
# @example
|
5
5
|
# [{"certRequestId"=>"B23Q2P396B",
|
@@ -37,9 +37,9 @@ module FastlaneCore
|
|
37
37
|
ret_certs = []
|
38
38
|
|
39
39
|
# Select certificate
|
40
|
-
certificate_name =
|
41
|
-
cert_date =
|
42
|
-
cert_id =
|
40
|
+
certificate_name = Sigh.config[:cert_owner_name]
|
41
|
+
cert_date = Sigh.config[:cert_date]
|
42
|
+
cert_id = Sigh.config[:cert_id]
|
43
43
|
|
44
44
|
# The other profiles are push profiles
|
45
45
|
certificate_type = type == DEVELOPMENT ? 'iOS Development' : 'iOS Distribution'
|
data/lib/sigh/options.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'fastlane_core'
|
2
|
+
|
3
|
+
module Sigh
|
4
|
+
class Options
|
5
|
+
def self.available_options
|
6
|
+
@@options ||= [
|
7
|
+
FastlaneCore::ConfigItem.new(key: :adhoc,
|
8
|
+
env_name: "SIGH_AD_HOC",
|
9
|
+
description: "Setting this flag will generate AdHoc profiles instead of App Store Profiles",
|
10
|
+
is_string: false),
|
11
|
+
FastlaneCore::ConfigItem.new(key: :skip_install,
|
12
|
+
env_name: "SIGH_SKIP_INSTALL",
|
13
|
+
description: "By default, the certificate will be added on your local machine. Setting this flag will skip this action",
|
14
|
+
is_string: false),
|
15
|
+
FastlaneCore::ConfigItem.new(key: :development,
|
16
|
+
env_name: "SIGH_DEVELOPMENT",
|
17
|
+
description: "Renew the development certificate instead of the production one",
|
18
|
+
is_string: false),
|
19
|
+
FastlaneCore::ConfigItem.new(key: :force,
|
20
|
+
env_name: "SIGH_FORCE",
|
21
|
+
description: "Renew non-development provisioning profiles regardless of its state",
|
22
|
+
is_string: false),
|
23
|
+
FastlaneCore::ConfigItem.new(key: :app_identifier,
|
24
|
+
short_option: "-a",
|
25
|
+
env_name: "SIGH_APP_IDENTIFIER",
|
26
|
+
description: "The bundle identifier of your app",
|
27
|
+
default_value: CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)),
|
28
|
+
FastlaneCore::ConfigItem.new(key: :username,
|
29
|
+
short_option: "-u",
|
30
|
+
env_name: "SIGH_USERNAME",
|
31
|
+
description: "Your Apple ID Username",
|
32
|
+
default_value: CredentialsManager::AppfileConfig.try_fetch_value(:apple_id),
|
33
|
+
verify_block: Proc.new do |value|
|
34
|
+
CredentialsManager::PasswordManager.shared_manager(value)
|
35
|
+
end),
|
36
|
+
FastlaneCore::ConfigItem.new(key: :provisioning_file_name,
|
37
|
+
short_option: "-n",
|
38
|
+
env_name: "SIGH_PROVISIONING_PROFILE_NAME",
|
39
|
+
description: "The name of the generated certificate file"),
|
40
|
+
FastlaneCore::ConfigItem.new(key: :output_path,
|
41
|
+
short_option: "-o",
|
42
|
+
env_name: "SIGH_OUTPUT_PATH",
|
43
|
+
description: "Directory in which the profile should be stored",
|
44
|
+
default_value: ".",
|
45
|
+
verify_block: Proc.new do |value|
|
46
|
+
raise "Could not find output directory '#{value}'".red unless File.exists?(value)
|
47
|
+
end),
|
48
|
+
FastlaneCore::ConfigItem.new(key: :cert_id,
|
49
|
+
short_option: "-i",
|
50
|
+
env_name: "SIGH_CERTIFICATE_ID",
|
51
|
+
description: "The ID of the certificate to use",
|
52
|
+
optional: true),
|
53
|
+
FastlaneCore::ConfigItem.new(key: :cert_owner_name,
|
54
|
+
short_option: "-c",
|
55
|
+
env_name: "SIGH_CERTIFICATE",
|
56
|
+
description: "The certificate name to use for new profiles, or to renew with. (e.g. \"Felix Krause\")",
|
57
|
+
optional: true),
|
58
|
+
FastlaneCore::ConfigItem.new(key: :cert_date,
|
59
|
+
short_option: "-d",
|
60
|
+
env_name: "SIGH_CERTIFICATE_EXPIRE_DATE",
|
61
|
+
description: "The certificate with the given expiry date used to renew. (e.g. \"Nov 11, 2017\")",
|
62
|
+
optional: true),
|
63
|
+
FastlaneCore::ConfigItem.new(key: :filename,
|
64
|
+
short_option: "-f",
|
65
|
+
env_name: "SIGH_PROFILE_FILE_NAME",
|
66
|
+
optional: true,
|
67
|
+
description: "Filename to use for the generated provisioning profile (must include .mobileprovision)",
|
68
|
+
verify_block: Proc.new do |value|
|
69
|
+
raise "The output name must end with .mobileprovision".red unless value.end_with?".mobileprovision"
|
70
|
+
end)
|
71
|
+
]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -3,7 +3,7 @@ require 'plist'
|
|
3
3
|
module Sigh
|
4
4
|
class ProfileAnalyser
|
5
5
|
def self.run(path)
|
6
|
-
plist = Plist::parse_xml(`security cms -D -i #{path}`)
|
6
|
+
plist = Plist::parse_xml(`security cms -D -i '#{path}'`)
|
7
7
|
if plist.count > 10
|
8
8
|
Helper.log.info("Provisioning profile of app '#{plist['AppIDName']}' with the name '#{plist['Name']}' successfully generated and analysed.".green)
|
9
9
|
return plist["UUID"]
|
data/lib/sigh/resign.rb
CHANGED
@@ -1,60 +1,92 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
|
1
3
|
module Sigh
|
2
4
|
# Resigns an existing ipa file
|
3
5
|
class Resign
|
4
6
|
def run(options, args)
|
5
|
-
|
7
|
+
# get the command line inputs and parse those into the vars we need...
|
8
|
+
ipa, signing_identity, provisioning_profile = get_inputs(options, args)
|
9
|
+
|
10
|
+
# ... then invoke out programmatic interface with these vars
|
11
|
+
resign(ipa, signing_identity, provisioning_profile)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.resign(ipa, signing_identity, provisioning_profile)
|
15
|
+
self.new.resign(ipa, signing_identity, provisioning_profile)
|
16
|
+
end
|
17
|
+
|
18
|
+
def resign(ipa, signing_identity, provisioning_profile)
|
19
|
+
resign_path = find_resign_path
|
20
|
+
signing_identity = find_signing_identity(signing_identity)
|
21
|
+
|
22
|
+
# validate that we have valid values for all these params, we don't need to check signing_identity because `find_signing_identity` will only ever return a valid value
|
23
|
+
validate_params(resign_path, ipa, provisioning_profile)
|
6
24
|
|
7
25
|
command = [
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
"-p
|
12
|
-
|
26
|
+
resign_path.shellescape,
|
27
|
+
ipa.shellescape,
|
28
|
+
signing_identity.shellescape,
|
29
|
+
"-p #{provisioning_profile.shellescape}",
|
30
|
+
ipa.shellescape
|
13
31
|
].join(' ')
|
14
32
|
|
15
33
|
puts command.magenta
|
16
34
|
output = `#{command}`
|
17
35
|
puts output
|
18
|
-
if output.include?
|
19
|
-
Helper.log.info "Successfully signed #{
|
36
|
+
if output.include?('Assuming Distribution Identity')
|
37
|
+
Helper.log.info "Successfully signed #{ipa}!".green
|
38
|
+
true
|
20
39
|
else
|
21
|
-
Helper.log.fatal "Something went wrong while code signing #{
|
40
|
+
Helper.log.fatal "Something went wrong while code signing #{ipa}".red
|
41
|
+
false
|
22
42
|
end
|
23
43
|
end
|
24
44
|
|
25
45
|
def get_inputs(options, args)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
46
|
+
ipa = args.first || find_ipa || ask('Path to ipa file: ')
|
47
|
+
signing_identity = options.signing_identity || ask_for_signing_identity
|
48
|
+
provisioning_profile = options.provisioning_profile || find_provisioning_profile || ask('Path to provisioning file: ')
|
49
|
+
|
50
|
+
return ipa, signing_identity, provisioning_profile
|
51
|
+
end
|
52
|
+
|
53
|
+
def find_resign_path
|
54
|
+
File.join(Helper.gem_path('sigh'), 'lib', 'assets', 'resign.sh')
|
35
55
|
end
|
36
56
|
|
37
57
|
def find_ipa
|
38
|
-
Dir[File.join(Dir.pwd,
|
58
|
+
Dir[File.join(Dir.pwd, '*.ipa')].sort { |a, b| File.mtime(a) <=> File.mtime(b) }.first
|
39
59
|
end
|
40
60
|
|
41
61
|
def find_provisioning_profile
|
42
|
-
Dir[File.join(Dir.pwd,
|
62
|
+
Dir[File.join(Dir.pwd, '*.mobileprovision')].sort { |a, b| File.mtime(a) <=> File.mtime(b) }.first
|
43
63
|
end
|
44
64
|
|
45
|
-
def
|
46
|
-
|
65
|
+
def find_signing_identity(signing_identity)
|
66
|
+
until installed_identies.include?(signing_identity)
|
67
|
+
Helper.log.error "Couldn't find signing identity '#{signing_identity}'."
|
68
|
+
signing_identity = ask_for_signing_identity
|
69
|
+
end
|
70
|
+
|
71
|
+
signing_identity
|
47
72
|
end
|
48
73
|
|
49
|
-
def
|
50
|
-
|
74
|
+
def validate_params(resign_path, ipa, provisioning_profile)
|
75
|
+
validate_resign_path(resign_path)
|
76
|
+
validate_ipa_file(ipa)
|
77
|
+
validate_provisioning_file(provisioning_profile)
|
51
78
|
end
|
52
79
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
80
|
+
def validate_resign_path(resign_path)
|
81
|
+
raise 'Could not find resign.sh file. Please try re-installing the gem.'.red unless File.exist?(resign_path)
|
82
|
+
end
|
83
|
+
|
84
|
+
def validate_ipa_file(ipa)
|
85
|
+
raise "ipa file could not be found or is not an ipa file (#{ipa})".red unless File.exist?(ipa) && ipa.end_with?('.ipa')
|
86
|
+
end
|
87
|
+
|
88
|
+
def validate_provisioning_file(provisioning_profile)
|
89
|
+
raise "Provisioning profile file could not be found or is not a .mobileprovision file (#{provisioning_profile})".red unless File.exists?(provisioning_profile) && provisioning_profile.end_with?('.mobileprovision')
|
58
90
|
end
|
59
91
|
|
60
92
|
def print_available_identities
|
@@ -63,7 +95,7 @@ module Sigh
|
|
63
95
|
|
64
96
|
def ask_for_signing_identity
|
65
97
|
print_available_identities
|
66
|
-
ask(
|
98
|
+
ask('Signing Identity: ')
|
67
99
|
end
|
68
100
|
|
69
101
|
# Array of available signing identities
|
@@ -74,7 +106,7 @@ module Sigh
|
|
74
106
|
(ids << current.match(/.*\"(.*)\"/)[1]) rescue nil # the last line does not match
|
75
107
|
end
|
76
108
|
|
77
|
-
|
109
|
+
ids
|
78
110
|
end
|
79
111
|
end
|
80
|
-
end
|
112
|
+
end
|
data/lib/sigh/version.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sigh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Krause
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fastlane_core
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.3.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.3.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: plist
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -153,10 +153,11 @@ files:
|
|
153
153
|
- lib/sigh/dependency_checker.rb
|
154
154
|
- lib/sigh/developer_center.rb
|
155
155
|
- lib/sigh/developer_center_signing.rb
|
156
|
+
- lib/sigh/options.rb
|
156
157
|
- lib/sigh/profile_analyser.rb
|
157
158
|
- lib/sigh/resign.rb
|
158
159
|
- lib/sigh/version.rb
|
159
|
-
homepage:
|
160
|
+
homepage: https://fastlane.tools
|
160
161
|
licenses:
|
161
162
|
- MIT
|
162
163
|
metadata: {}
|