fastlane 2.128.0.beta.20190722200021 → 2.128.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.md +64 -64
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +10 -0
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/Fastlane.swift +5 -5
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/match/lib/match.rb +1 -0
- data/match/lib/match/commands_generator.rb +14 -0
- data/match/lib/match/generator.rb +2 -2
- data/match/lib/match/importer.rb +92 -0
- data/match/lib/match/runner.rb +20 -42
- data/match/lib/match/storage/git_storage.rb +4 -0
- data/match/lib/match/storage/google_cloud_storage.rb +46 -2
- data/match/lib/match/storage/interface.rb +5 -0
- metadata +29 -29
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: cfbcd2e9eb321099998ee88a73eb4d57b48835bbfda6f1e463f5116099ca43e6
|
|
4
|
+
data.tar.gz: f0013718dfe75e9282d2917642754498ad73486244ba32d804500f88889dcf25
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b2cbd0d9169e59413d82340364983e036d1a90ffc73cf8062f67b1278265f4464554d9a35ee9285c3df1bfa20f21b3dec1d9617f1c04744d41c48ef8e39f5fcd
|
|
7
|
+
data.tar.gz: 0362bbb52b555bc5036c4be2261f1e3549d8eba8b827f3956e6c7af1a01d522dcee20fbb5a27c7cf3970b4a2f381ef4caba136e59cfba4bfde1d9a697beaf318
|
data/README.md
CHANGED
|
@@ -34,17 +34,11 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
|
|
|
34
34
|
<!-- This table is regenerated and resorted on each release -->
|
|
35
35
|
<table id='team'>
|
|
36
36
|
<tr>
|
|
37
|
-
<td id='
|
|
38
|
-
<a href='https://github.com/
|
|
39
|
-
<img src='https://github.com/
|
|
40
|
-
</a>
|
|
41
|
-
<h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
|
|
42
|
-
</td>
|
|
43
|
-
<td id='danielle-tomlinson'>
|
|
44
|
-
<a href='https://github.com/endocrimes'>
|
|
45
|
-
<img src='https://github.com/endocrimes.png?size=140'>
|
|
37
|
+
<td id='iulian-onofrei'>
|
|
38
|
+
<a href='https://github.com/revolter'>
|
|
39
|
+
<img src='https://github.com/revolter.png?size=140'>
|
|
46
40
|
</a>
|
|
47
|
-
<h4 align='center'><a href='https://twitter.com/
|
|
41
|
+
<h4 align='center'><a href='https://twitter.com/Revolt666'>Iulian Onofrei</a></h4>
|
|
48
42
|
</td>
|
|
49
43
|
<td id='andrew-mcburney'>
|
|
50
44
|
<a href='https://github.com/armcburney'>
|
|
@@ -52,11 +46,17 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
|
|
|
52
46
|
</a>
|
|
53
47
|
<h4 align='center'><a href='https://twitter.com/armcburney'>Andrew McBurney</a></h4>
|
|
54
48
|
</td>
|
|
55
|
-
<td id='
|
|
56
|
-
<a href='https://github.com/
|
|
57
|
-
<img src='https://github.com/
|
|
49
|
+
<td id='fumiya-nakamura'>
|
|
50
|
+
<a href='https://github.com/nafu'>
|
|
51
|
+
<img src='https://github.com/nafu.png?size=140'>
|
|
58
52
|
</a>
|
|
59
|
-
<h4 align='center'><a href='https://twitter.com/
|
|
53
|
+
<h4 align='center'><a href='https://twitter.com/nafu003'>Fumiya Nakamura</a></h4>
|
|
54
|
+
</td>
|
|
55
|
+
<td id='helmut-januschka'>
|
|
56
|
+
<a href='https://github.com/hjanuschka'>
|
|
57
|
+
<img src='https://github.com/hjanuschka.png?size=140'>
|
|
58
|
+
</a>
|
|
59
|
+
<h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
|
|
60
60
|
</td>
|
|
61
61
|
<td id='felix-krause'>
|
|
62
62
|
<a href='https://github.com/KrauseFx'>
|
|
@@ -66,11 +66,11 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
|
|
|
66
66
|
</td>
|
|
67
67
|
</tr>
|
|
68
68
|
<tr>
|
|
69
|
-
<td id='
|
|
70
|
-
<a href='https://github.com/
|
|
71
|
-
<img src='https://github.com/
|
|
69
|
+
<td id='aaron-brager'>
|
|
70
|
+
<a href='https://github.com/getaaron'>
|
|
71
|
+
<img src='https://github.com/getaaron.png?size=140'>
|
|
72
72
|
</a>
|
|
73
|
-
<h4 align='center'><a href='https://twitter.com/
|
|
73
|
+
<h4 align='center'><a href='https://twitter.com/getaaron'>Aaron Brager</a></h4>
|
|
74
74
|
</td>
|
|
75
75
|
<td id='stefan-natchev'>
|
|
76
76
|
<a href='https://github.com/snatchev'>
|
|
@@ -78,43 +78,49 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
|
|
|
78
78
|
</a>
|
|
79
79
|
<h4 align='center'><a href='https://twitter.com/snatchev'>Stefan Natchev</a></h4>
|
|
80
80
|
</td>
|
|
81
|
-
<td id='
|
|
82
|
-
<a href='https://github.com/
|
|
83
|
-
<img src='https://github.com/
|
|
84
|
-
</a>
|
|
85
|
-
<h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
|
|
86
|
-
</td>
|
|
87
|
-
<td id='aaron-brager'>
|
|
88
|
-
<a href='https://github.com/getaaron'>
|
|
89
|
-
<img src='https://github.com/getaaron.png?size=140'>
|
|
81
|
+
<td id='maksym-grebenets'>
|
|
82
|
+
<a href='https://github.com/mgrebenets'>
|
|
83
|
+
<img src='https://github.com/mgrebenets.png?size=140'>
|
|
90
84
|
</a>
|
|
91
|
-
<h4 align='center'><a href='https://twitter.com/
|
|
85
|
+
<h4 align='center'><a href='https://twitter.com/mgrebenets'>Maksym Grebenets</a></h4>
|
|
92
86
|
</td>
|
|
93
|
-
<td id='
|
|
94
|
-
<a href='https://github.com/
|
|
95
|
-
<img src='https://github.com/
|
|
87
|
+
<td id='olivier-halligon'>
|
|
88
|
+
<a href='https://github.com/AliSoftware'>
|
|
89
|
+
<img src='https://github.com/AliSoftware.png?size=140'>
|
|
96
90
|
</a>
|
|
97
|
-
<h4 align='center'><a href='https://twitter.com/
|
|
91
|
+
<h4 align='center'><a href='https://twitter.com/aligatr'>Olivier Halligon</a></h4>
|
|
98
92
|
</td>
|
|
99
|
-
</tr>
|
|
100
|
-
<tr>
|
|
101
93
|
<td id='jimmy-dee'>
|
|
102
94
|
<a href='https://github.com/jdee'>
|
|
103
95
|
<img src='https://github.com/jdee.png?size=140'>
|
|
104
96
|
</a>
|
|
105
97
|
<h4 align='center'>Jimmy Dee</h4>
|
|
106
98
|
</td>
|
|
107
|
-
|
|
108
|
-
<
|
|
109
|
-
<
|
|
99
|
+
</tr>
|
|
100
|
+
<tr>
|
|
101
|
+
<td id='kohki-miki'>
|
|
102
|
+
<a href='https://github.com/giginet'>
|
|
103
|
+
<img src='https://github.com/giginet.png?size=140'>
|
|
110
104
|
</a>
|
|
111
|
-
<h4 align='center'><a href='https://twitter.com/
|
|
105
|
+
<h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
|
|
112
106
|
</td>
|
|
113
|
-
<td id='
|
|
114
|
-
<a href='https://github.com/
|
|
115
|
-
<img src='https://github.com/
|
|
107
|
+
<td id='josh-holtz'>
|
|
108
|
+
<a href='https://github.com/joshdholtz'>
|
|
109
|
+
<img src='https://github.com/joshdholtz.png?size=140'>
|
|
116
110
|
</a>
|
|
117
|
-
<h4 align='center'><a href='https://twitter.com/
|
|
111
|
+
<h4 align='center'><a href='https://twitter.com/joshdholtz'>Josh Holtz</a></h4>
|
|
112
|
+
</td>
|
|
113
|
+
<td id='matthew-ellis'>
|
|
114
|
+
<a href='https://github.com/matthewellis'>
|
|
115
|
+
<img src='https://github.com/matthewellis.png?size=140'>
|
|
116
|
+
</a>
|
|
117
|
+
<h4 align='center'><a href='https://twitter.com/mellis1995'>Matthew Ellis</a></h4>
|
|
118
|
+
</td>
|
|
119
|
+
<td id='manu-wallner'>
|
|
120
|
+
<a href='https://github.com/milch'>
|
|
121
|
+
<img src='https://github.com/milch.png?size=140'>
|
|
122
|
+
</a>
|
|
123
|
+
<h4 align='center'><a href='https://twitter.com/acrooow'>Manu Wallner</a></h4>
|
|
118
124
|
</td>
|
|
119
125
|
<td id='joshua-liebowitz'>
|
|
120
126
|
<a href='https://github.com/taquitos'>
|
|
@@ -122,12 +128,6 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
|
|
|
122
128
|
</a>
|
|
123
129
|
<h4 align='center'><a href='https://twitter.com/taquitos'>Joshua Liebowitz</a></h4>
|
|
124
130
|
</td>
|
|
125
|
-
<td id='kohki-miki'>
|
|
126
|
-
<a href='https://github.com/giginet'>
|
|
127
|
-
<img src='https://github.com/giginet.png?size=140'>
|
|
128
|
-
</a>
|
|
129
|
-
<h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
|
|
130
|
-
</td>
|
|
131
131
|
</tr>
|
|
132
132
|
<tr>
|
|
133
133
|
<td id='luka-mirosevic'>
|
|
@@ -136,29 +136,29 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
|
|
|
136
136
|
</a>
|
|
137
137
|
<h4 align='center'><a href='https://twitter.com/lmirosevic'>Luka Mirosevic</a></h4>
|
|
138
138
|
</td>
|
|
139
|
-
<td id='
|
|
140
|
-
<a href='https://github.com/
|
|
141
|
-
<img src='https://github.com/
|
|
139
|
+
<td id='jan-piotrowski'>
|
|
140
|
+
<a href='https://github.com/janpio'>
|
|
141
|
+
<img src='https://github.com/janpio.png?size=140'>
|
|
142
142
|
</a>
|
|
143
|
-
<h4 align='center'><a href='https://twitter.com/
|
|
143
|
+
<h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
|
|
144
144
|
</td>
|
|
145
|
-
<td id='
|
|
146
|
-
<a href='https://github.com/
|
|
147
|
-
<img src='https://github.com/
|
|
145
|
+
<td id='danielle-tomlinson'>
|
|
146
|
+
<a href='https://github.com/endocrimes'>
|
|
147
|
+
<img src='https://github.com/endocrimes.png?size=140'>
|
|
148
148
|
</a>
|
|
149
|
-
<h4 align='center'><a href='https://twitter.com/
|
|
149
|
+
<h4 align='center'><a href='https://twitter.com/endocrimes'>Danielle Tomlinson</a></h4>
|
|
150
150
|
</td>
|
|
151
|
-
<td id='
|
|
152
|
-
<a href='https://github.com/
|
|
153
|
-
<img src='https://github.com/
|
|
151
|
+
<td id='jorge-revuelta-h'>
|
|
152
|
+
<a href='https://github.com/minuscorp'>
|
|
153
|
+
<img src='https://github.com/minuscorp.png?size=140'>
|
|
154
154
|
</a>
|
|
155
|
-
<h4 align='center'><a href='https://twitter.com/
|
|
155
|
+
<h4 align='center'><a href='https://twitter.com/minuscorp'>Jorge Revuelta H</a></h4>
|
|
156
156
|
</td>
|
|
157
|
-
<td id='
|
|
158
|
-
<a href='https://github.com/
|
|
159
|
-
<img src='https://github.com/
|
|
157
|
+
<td id='jérôme-lacoste'>
|
|
158
|
+
<a href='https://github.com/lacostej'>
|
|
159
|
+
<img src='https://github.com/lacostej.png?size=140'>
|
|
160
160
|
</a>
|
|
161
|
-
<h4 align='center'><a href='https://twitter.com/
|
|
161
|
+
<h4 align='center'><a href='https://twitter.com/lacostej'>Jérôme Lacoste</a></h4>
|
|
162
162
|
</td>
|
|
163
163
|
</tr>
|
|
164
164
|
</table>
|
|
@@ -407,6 +407,16 @@ fastlane match change_password
|
|
|
407
407
|
|
|
408
408
|
You'll be asked for the new password on all your machines on the next run.
|
|
409
409
|
|
|
410
|
+
### Import
|
|
411
|
+
|
|
412
|
+
To import and encrypt a certificate (`.cer`) and the private key (`.p12`) into the _match_ repo run:
|
|
413
|
+
|
|
414
|
+
```no-highlight
|
|
415
|
+
fastlane match import
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
You'll be prompted for the certificate (`.cer`) and the private key (`.p12`) paths. _match_ will first validate the certificate (`.cer`) against the Developer Portal before importing the certificate (`.cer`) and the private key (`.p12`).
|
|
419
|
+
|
|
410
420
|
### Manual Decrypt
|
|
411
421
|
|
|
412
422
|
If you want to manually decrypt a file you can.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module Fastlane
|
|
2
|
-
VERSION = '2.128.0
|
|
2
|
+
VERSION = '2.128.0'.freeze
|
|
3
3
|
DESCRIPTION = "The easiest way to automate beta deployments and releases for your iOS and Android apps".freeze
|
|
4
4
|
MINIMUM_XCODE_RELEASE = "7.0".freeze
|
|
5
5
|
RUBOCOP_REQUIREMENT = '0.49.1'.freeze
|
|
@@ -1406,7 +1406,7 @@ func downloadDsyms(username: String,
|
|
|
1406
1406
|
_ = runner.executeCommand(command)
|
|
1407
1407
|
}
|
|
1408
1408
|
func downloadFromPlayStore(packageName: String,
|
|
1409
|
-
metadataPath: String =
|
|
1409
|
+
metadataPath: String? = nil,
|
|
1410
1410
|
key: String? = nil,
|
|
1411
1411
|
issuer: String? = nil,
|
|
1412
1412
|
jsonKey: String? = nil,
|
|
@@ -3498,7 +3498,7 @@ func ssh(username: String,
|
|
|
3498
3498
|
func supply(packageName: String,
|
|
3499
3499
|
track: String = "production",
|
|
3500
3500
|
rollout: String? = nil,
|
|
3501
|
-
metadataPath: String =
|
|
3501
|
+
metadataPath: String? = nil,
|
|
3502
3502
|
key: String? = nil,
|
|
3503
3503
|
issuer: String? = nil,
|
|
3504
3504
|
jsonKey: String? = nil,
|
|
@@ -4034,7 +4034,7 @@ func uploadToAppStore(username: String,
|
|
|
4034
4034
|
func uploadToPlayStore(packageName: String,
|
|
4035
4035
|
track: String = "production",
|
|
4036
4036
|
rollout: String? = nil,
|
|
4037
|
-
metadataPath: String =
|
|
4037
|
+
metadataPath: String? = nil,
|
|
4038
4038
|
key: String? = nil,
|
|
4039
4039
|
issuer: String? = nil,
|
|
4040
4040
|
jsonKey: String? = nil,
|
|
@@ -4285,7 +4285,7 @@ func xcov(workspace: String? = nil,
|
|
|
4285
4285
|
coverallsServiceJobId: String? = nil,
|
|
4286
4286
|
coverallsRepoToken: String? = nil,
|
|
4287
4287
|
xcconfig: String? = nil,
|
|
4288
|
-
ideFoundationPath: String = "/Applications/
|
|
4288
|
+
ideFoundationPath: String = "/Applications/Xcode10.1.app/Contents/Developer/../Frameworks/IDEFoundation.framework/Versions/A/IDEFoundation",
|
|
4289
4289
|
legacySupport: Bool = false) {
|
|
4290
4290
|
let command = RubyCommand(commandID: "", methodName: "xcov", className: nil, args: [RubyCommand.Argument(name: "workspace", value: workspace),
|
|
4291
4291
|
RubyCommand.Argument(name: "project", value: project),
|
|
@@ -4395,4 +4395,4 @@ let screengrabfile: Screengrabfile = Screengrabfile()
|
|
|
4395
4395
|
let snapshotfile: Snapshotfile = Snapshotfile()
|
|
4396
4396
|
// Please don't remove the lines below
|
|
4397
4397
|
// They are used to detect outdated files
|
|
4398
|
-
// FastlaneRunnerAPIVersion [0.9.
|
|
4398
|
+
// FastlaneRunnerAPIVersion [0.9.53]
|
data/match/lib/match.rb
CHANGED
|
@@ -8,6 +8,7 @@ require_relative 'match/setup'
|
|
|
8
8
|
require_relative 'match/spaceship_ensure'
|
|
9
9
|
require_relative 'match/change_password'
|
|
10
10
|
require_relative 'match/migrate'
|
|
11
|
+
require_relative 'match/importer'
|
|
11
12
|
require_relative 'match/storage'
|
|
12
13
|
require_relative 'match/encryption'
|
|
13
14
|
require_relative 'match/module'
|
|
@@ -8,6 +8,7 @@ require_relative 'setup'
|
|
|
8
8
|
require_relative 'runner'
|
|
9
9
|
require_relative 'options'
|
|
10
10
|
require_relative 'migrate'
|
|
11
|
+
require_relative 'importer'
|
|
11
12
|
|
|
12
13
|
require_relative 'storage'
|
|
13
14
|
require_relative 'encryption'
|
|
@@ -132,6 +133,19 @@ module Match
|
|
|
132
133
|
end
|
|
133
134
|
end
|
|
134
135
|
|
|
136
|
+
command :import do |c|
|
|
137
|
+
c.syntax = "fastlane match import"
|
|
138
|
+
c.description = "Imports certificates and profiles into the encrypted repository"
|
|
139
|
+
|
|
140
|
+
FastlaneCore::CommanderGenerator.new.generate(Match::Options.available_options, command: c)
|
|
141
|
+
|
|
142
|
+
c.action do |args, options|
|
|
143
|
+
params = FastlaneCore::Configuration.create(Match::Options.available_options, options.__hash__)
|
|
144
|
+
params.load_configuration_file("Matchfile") # this has to be done *before* overwriting the value
|
|
145
|
+
Match::Importer.new.import_cert(params)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
135
149
|
command :migrate do |c|
|
|
136
150
|
c.syntax = "fastlane match migrate"
|
|
137
151
|
c.description = "Migrate from one storage backend to another one"
|
|
@@ -41,7 +41,7 @@ module Match
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
# @return (String) The UUID of the newly generated profile
|
|
44
|
-
def self.generate_provisioning_profile(params: nil, prov_type: nil, certificate_id: nil, app_identifier: nil, working_directory: nil)
|
|
44
|
+
def self.generate_provisioning_profile(params: nil, prov_type: nil, certificate_id: nil, app_identifier: nil, force: true, working_directory: nil)
|
|
45
45
|
require 'sigh/manager'
|
|
46
46
|
require 'sigh/options'
|
|
47
47
|
|
|
@@ -59,7 +59,7 @@ module Match
|
|
|
59
59
|
app_identifier: app_identifier,
|
|
60
60
|
output_path: File.join(working_directory, "profiles", prov_type.to_s),
|
|
61
61
|
username: params[:username],
|
|
62
|
-
force:
|
|
62
|
+
force: force,
|
|
63
63
|
cert_id: certificate_id,
|
|
64
64
|
provisioning_name: profile_name,
|
|
65
65
|
ignore_profiles_with_different_name: true,
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require_relative 'spaceship_ensure'
|
|
2
|
+
require_relative 'encryption'
|
|
3
|
+
require_relative 'storage'
|
|
4
|
+
require_relative 'module'
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
|
|
7
|
+
module Match
|
|
8
|
+
class Importer
|
|
9
|
+
def import_cert(params, cert_path: nil, p12_path: nil)
|
|
10
|
+
# Get and verify cert and p12 path
|
|
11
|
+
cert_path ||= UI.input("Certificate (.cer) path:")
|
|
12
|
+
p12_path ||= UI.input("Private key (.p12) path:")
|
|
13
|
+
|
|
14
|
+
cert_path = File.absolute_path(cert_path)
|
|
15
|
+
p12_path = File.absolute_path(p12_path)
|
|
16
|
+
|
|
17
|
+
UI.user_error!("Certificate does not exist at path: #{cert_path}") unless File.exist?(cert_path)
|
|
18
|
+
UI.user_error!("Private key does not exist at path: #{p12_path}") unless File.exist?(p12_path)
|
|
19
|
+
|
|
20
|
+
# Base64 encrypt contents to find match from API to find a cert ID
|
|
21
|
+
cert_contents_base_64 = Base64.strict_encode64(File.open(cert_path).read)
|
|
22
|
+
|
|
23
|
+
# Storage
|
|
24
|
+
storage = Storage.for_mode(params[:storage_mode], {
|
|
25
|
+
git_url: params[:git_url],
|
|
26
|
+
shallow_clone: params[:shallow_clone],
|
|
27
|
+
skip_docs: params[:skip_docs],
|
|
28
|
+
git_branch: params[:git_branch],
|
|
29
|
+
git_full_name: params[:git_full_name],
|
|
30
|
+
git_user_email: params[:git_user_email],
|
|
31
|
+
clone_branch_directly: params[:clone_branch_directly],
|
|
32
|
+
type: params[:type].to_s,
|
|
33
|
+
platform: params[:platform].to_s,
|
|
34
|
+
google_cloud_bucket_name: params[:google_cloud_bucket_name].to_s,
|
|
35
|
+
google_cloud_keys_file: params[:google_cloud_keys_file].to_s,
|
|
36
|
+
google_cloud_project_id: params[:google_cloud_project_id].to_s,
|
|
37
|
+
readonly: params[:readonly],
|
|
38
|
+
username: params[:username],
|
|
39
|
+
team_id: params[:team_id],
|
|
40
|
+
team_name: params[:team_name]
|
|
41
|
+
})
|
|
42
|
+
storage.download
|
|
43
|
+
|
|
44
|
+
# Encryption
|
|
45
|
+
encryption = Encryption.for_storage_mode(params[:storage_mode], {
|
|
46
|
+
git_url: params[:git_url],
|
|
47
|
+
working_directory: storage.working_directory
|
|
48
|
+
})
|
|
49
|
+
encryption.decrypt_files if encryption
|
|
50
|
+
UI.success("Repo is at: '#{storage.working_directory}'")
|
|
51
|
+
|
|
52
|
+
# Map match type into Spaceship::ConnectAPI::Certificate::CertificateType
|
|
53
|
+
cert_type = Match.cert_type_sym(params[:type])
|
|
54
|
+
|
|
55
|
+
case cert_type
|
|
56
|
+
when :development
|
|
57
|
+
certificate_type = Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DEVELOPMENT
|
|
58
|
+
when :distribution, :enterprise
|
|
59
|
+
certificate_type = Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DISTRIBUTION
|
|
60
|
+
else
|
|
61
|
+
UI.user_error!("Cert type '#{cert_type}' is not supported")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
output_dir = File.join(storage.prefixed_working_directory, "certs", cert_type.to_s)
|
|
65
|
+
|
|
66
|
+
# Need to get the cert id by comparing base64 encoded cert content with certificate content from the API responses
|
|
67
|
+
Spaceship::Portal.login(params[:username])
|
|
68
|
+
Spaceship::Portal.select_team(team_id: params[:team_id], team_name: params[:team_name])
|
|
69
|
+
certs = Spaceship::ConnectAPI::Certificate.all(filter: { certificateType: certificate_type })
|
|
70
|
+
|
|
71
|
+
matching_cert = certs.find do |cert|
|
|
72
|
+
cert.certificate_content == cert_contents_base_64
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
UI.error!("This certificate cannot be imported - the certificate contents did not match with any available on the Developer Portal") if matching_cert.nil?
|
|
76
|
+
|
|
77
|
+
# Make dir if doesn't exist
|
|
78
|
+
FileUtils.mkdir_p(output_dir)
|
|
79
|
+
dest_cert_path = File.join(output_dir, "#{matching_cert.id}.cer")
|
|
80
|
+
dest_p12_path = File.join(output_dir, "#{matching_cert.id}.p12")
|
|
81
|
+
|
|
82
|
+
# Copy files
|
|
83
|
+
IO.copy_stream(cert_path, dest_cert_path)
|
|
84
|
+
IO.copy_stream(p12_path, dest_p12_path)
|
|
85
|
+
files_to_commit = [dest_cert_path, dest_p12_path]
|
|
86
|
+
|
|
87
|
+
# Encrypt and commit
|
|
88
|
+
encryption.encrypt_files if encryption
|
|
89
|
+
storage.save_changes!(files_to_commit: files_to_commit)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
data/match/lib/match/runner.rb
CHANGED
|
@@ -16,11 +16,7 @@ module Match
|
|
|
16
16
|
attr_accessor :files_to_commit
|
|
17
17
|
attr_accessor :spaceship
|
|
18
18
|
|
|
19
|
-
attr_accessor :
|
|
20
|
-
|
|
21
|
-
# The Team ID that was fetched
|
|
22
|
-
# This will always be `nil` in readonly mode
|
|
23
|
-
attr_accessor :currently_used_team_id
|
|
19
|
+
attr_accessor :storage
|
|
24
20
|
|
|
25
21
|
def run(params)
|
|
26
22
|
self.files_to_commit = []
|
|
@@ -32,10 +28,8 @@ module Match
|
|
|
32
28
|
|
|
33
29
|
update_optional_values_depending_on_storage_type(params)
|
|
34
30
|
|
|
35
|
-
self.storage_mode = params[:storage_mode]
|
|
36
|
-
|
|
37
31
|
# Choose the right storage and encryption implementations
|
|
38
|
-
storage = Storage.for_mode(params[:storage_mode], {
|
|
32
|
+
self.storage = Storage.for_mode(params[:storage_mode], {
|
|
39
33
|
git_url: params[:git_url],
|
|
40
34
|
shallow_clone: params[:shallow_clone],
|
|
41
35
|
skip_docs: params[:skip_docs],
|
|
@@ -47,7 +41,11 @@ module Match
|
|
|
47
41
|
platform: params[:platform].to_s,
|
|
48
42
|
google_cloud_bucket_name: params[:google_cloud_bucket_name].to_s,
|
|
49
43
|
google_cloud_keys_file: params[:google_cloud_keys_file].to_s,
|
|
50
|
-
google_cloud_project_id: params[:google_cloud_project_id].to_s
|
|
44
|
+
google_cloud_project_id: params[:google_cloud_project_id].to_s,
|
|
45
|
+
readonly: params[:readonly],
|
|
46
|
+
username: params[:username],
|
|
47
|
+
team_id: params[:team_id],
|
|
48
|
+
team_name: params[:team_name]
|
|
51
49
|
})
|
|
52
50
|
storage.download
|
|
53
51
|
|
|
@@ -58,14 +56,8 @@ module Match
|
|
|
58
56
|
})
|
|
59
57
|
encryption.decrypt_files if encryption
|
|
60
58
|
|
|
61
|
-
|
|
62
|
-
# In readonly mode, we still want to see if the user provided a team_id
|
|
63
|
-
# see `prefixed_working_directory` comments for more details
|
|
64
|
-
self.currently_used_team_id = params[:team_id]
|
|
65
|
-
else
|
|
59
|
+
unless params[:readonly]
|
|
66
60
|
self.spaceship = SpaceshipEnsure.new(params[:username], params[:team_id], params[:team_name])
|
|
67
|
-
self.currently_used_team_id = self.spaceship.team_id
|
|
68
|
-
|
|
69
61
|
if params[:type] == "enterprise" && !Spaceship.client.in_house?
|
|
70
62
|
UI.user_error!("You defined the profile type 'enterprise', but your Apple account doesn't support In-House profiles")
|
|
71
63
|
end
|
|
@@ -124,25 +116,8 @@ module Match
|
|
|
124
116
|
end
|
|
125
117
|
|
|
126
118
|
# Used when creating a new certificate or profile
|
|
127
|
-
def prefixed_working_directory
|
|
128
|
-
|
|
129
|
-
return working_directory
|
|
130
|
-
elsif self.storage_mode == "google_cloud"
|
|
131
|
-
# We fall back to "*", which means certificates and profiles
|
|
132
|
-
# from all teams that use this bucket would be installed. This is not ideal, but
|
|
133
|
-
# unless the user provides a `team_id`, we can't know which one to use
|
|
134
|
-
# This only happens if `readonly` is activated, and no `team_id` was provided
|
|
135
|
-
@_folder_prefix ||= self.currently_used_team_id
|
|
136
|
-
if @_folder_prefix.nil?
|
|
137
|
-
# We use a `@_folder_prefix` variable, to keep state between multiple calls of this
|
|
138
|
-
# method, as the value won't change. This way the warning is only printed once
|
|
139
|
-
UI.important("Looks like you run `match` in `readonly` mode, and didn't provide a `team_id`. This will still work, however it is recommended to provide a `team_id` in your Appfile or Matchfile")
|
|
140
|
-
@_folder_prefix = "*"
|
|
141
|
-
end
|
|
142
|
-
return File.join(working_directory, @_folder_prefix)
|
|
143
|
-
else
|
|
144
|
-
UI.crash!("No implementation for `prefixed_working_directory`")
|
|
145
|
-
end
|
|
119
|
+
def prefixed_working_directory
|
|
120
|
+
return self.storage.prefixed_working_directory
|
|
146
121
|
end
|
|
147
122
|
|
|
148
123
|
# Be smart about optional values here
|
|
@@ -156,13 +131,13 @@ module Match
|
|
|
156
131
|
def fetch_certificate(params: nil, working_directory: nil)
|
|
157
132
|
cert_type = Match.cert_type_sym(params[:type])
|
|
158
133
|
|
|
159
|
-
certs = Dir[File.join(prefixed_working_directory
|
|
160
|
-
keys = Dir[File.join(prefixed_working_directory
|
|
134
|
+
certs = Dir[File.join(prefixed_working_directory, "certs", cert_type.to_s, "*.cer")]
|
|
135
|
+
keys = Dir[File.join(prefixed_working_directory, "certs", cert_type.to_s, "*.p12")]
|
|
161
136
|
|
|
162
137
|
if certs.count == 0 || keys.count == 0
|
|
163
138
|
UI.important("Couldn't find a valid code signing identity for #{cert_type}... creating one for you now")
|
|
164
139
|
UI.crash!("No code signing identity found and can not create a new one because you enabled `readonly`") if params[:readonly]
|
|
165
|
-
cert_path = Generator.generate_certificate(params, cert_type, prefixed_working_directory
|
|
140
|
+
cert_path = Generator.generate_certificate(params, cert_type, prefixed_working_directory)
|
|
166
141
|
private_key_path = cert_path.gsub(".cer", ".p12")
|
|
167
142
|
|
|
168
143
|
self.files_to_commit << cert_path
|
|
@@ -221,7 +196,7 @@ module Match
|
|
|
221
196
|
end
|
|
222
197
|
|
|
223
198
|
profile_name = names.join("_").gsub("*", '\*') # this is important, as it shouldn't be a wildcard
|
|
224
|
-
base_dir = File.join(prefixed_working_directory
|
|
199
|
+
base_dir = File.join(prefixed_working_directory, "profiles", prov_type.to_s)
|
|
225
200
|
profiles = Dir[File.join(base_dir, "#{profile_name}.mobileprovision")]
|
|
226
201
|
if Helper.mac?
|
|
227
202
|
keychain_path = FastlaneCore::Helper.keychain_path(params[:keychain_name]) unless params[:keychain_name].nil?
|
|
@@ -229,10 +204,11 @@ module Match
|
|
|
229
204
|
|
|
230
205
|
# Install the provisioning profiles
|
|
231
206
|
profile = profiles.last
|
|
207
|
+
force = params[:force]
|
|
232
208
|
|
|
233
209
|
if params[:force_for_new_devices] && !params[:readonly]
|
|
234
|
-
if prov_type != :appstore
|
|
235
|
-
|
|
210
|
+
if prov_type != :appstore && !params[:force]
|
|
211
|
+
force = device_count_different?(profile: profile, keychain_path: keychain_path, platform: params[:platform].to_sym)
|
|
236
212
|
else
|
|
237
213
|
# App Store provisioning profiles don't contain device identifiers and
|
|
238
214
|
# thus shouldn't be renewed if the device count has changed.
|
|
@@ -253,11 +229,13 @@ module Match
|
|
|
253
229
|
UI.error("If you are certain that a profile should exist, double-check the recent changes to your match repository")
|
|
254
230
|
UI.user_error!("No matching provisioning profiles found and can not create a new one because you enabled `readonly`. Check the output above for more information.")
|
|
255
231
|
end
|
|
232
|
+
|
|
256
233
|
profile = Generator.generate_provisioning_profile(params: params,
|
|
257
234
|
prov_type: prov_type,
|
|
258
235
|
certificate_id: certificate_id,
|
|
259
236
|
app_identifier: app_identifier,
|
|
260
|
-
|
|
237
|
+
force: force,
|
|
238
|
+
working_directory: prefixed_working_directory)
|
|
261
239
|
self.files_to_commit << profile
|
|
262
240
|
end
|
|
263
241
|
|
|
@@ -4,6 +4,7 @@ require 'google/cloud/storage'
|
|
|
4
4
|
|
|
5
5
|
require_relative '../options'
|
|
6
6
|
require_relative '../module'
|
|
7
|
+
require_relative '../spaceship_ensure'
|
|
7
8
|
require_relative './interface'
|
|
8
9
|
|
|
9
10
|
module Match
|
|
@@ -18,6 +19,10 @@ module Match
|
|
|
18
19
|
attr_reader :bucket_name
|
|
19
20
|
attr_reader :google_cloud_keys_file
|
|
20
21
|
attr_reader :google_cloud_project_id
|
|
22
|
+
attr_reader :readonly
|
|
23
|
+
attr_reader :username
|
|
24
|
+
attr_reader :team_id
|
|
25
|
+
attr_reader :team_name
|
|
21
26
|
|
|
22
27
|
# Managed values
|
|
23
28
|
attr_accessor :gc_storage
|
|
@@ -35,7 +40,11 @@ module Match
|
|
|
35
40
|
platform: params[:platform].to_s,
|
|
36
41
|
google_cloud_bucket_name: params[:google_cloud_bucket_name],
|
|
37
42
|
google_cloud_keys_file: params[:google_cloud_keys_file],
|
|
38
|
-
google_cloud_project_id: params[:google_cloud_project_id]
|
|
43
|
+
google_cloud_project_id: params[:google_cloud_project_id],
|
|
44
|
+
readonly: params[:readonly],
|
|
45
|
+
username: params[:username],
|
|
46
|
+
team_id: params[:team_id],
|
|
47
|
+
team_name: params[:team_name]
|
|
39
48
|
)
|
|
40
49
|
end
|
|
41
50
|
|
|
@@ -43,12 +52,21 @@ module Match
|
|
|
43
52
|
platform: nil,
|
|
44
53
|
google_cloud_bucket_name: nil,
|
|
45
54
|
google_cloud_keys_file: nil,
|
|
46
|
-
google_cloud_project_id: nil
|
|
55
|
+
google_cloud_project_id: nil,
|
|
56
|
+
readonly: nil,
|
|
57
|
+
username: nil,
|
|
58
|
+
team_id: nil,
|
|
59
|
+
team_name: nil)
|
|
47
60
|
@type = type if type
|
|
48
61
|
@platform = platform if platform
|
|
49
62
|
@google_cloud_project_id = google_cloud_project_id if google_cloud_project_id
|
|
50
63
|
@bucket_name = google_cloud_bucket_name
|
|
51
64
|
|
|
65
|
+
@readonly = readonly
|
|
66
|
+
@username = username
|
|
67
|
+
@team_id = team_id
|
|
68
|
+
@team_name = team_name
|
|
69
|
+
|
|
52
70
|
@google_cloud_keys_file = ensure_keys_file_exists(google_cloud_keys_file, google_cloud_project_id)
|
|
53
71
|
|
|
54
72
|
if self.google_cloud_keys_file.to_s.length > 0
|
|
@@ -81,6 +99,32 @@ module Match
|
|
|
81
99
|
ensure_bucket_is_selected
|
|
82
100
|
end
|
|
83
101
|
|
|
102
|
+
def currently_used_team_id
|
|
103
|
+
if self.readonly
|
|
104
|
+
# In readonly mode, we still want to see if the user provided a team_id
|
|
105
|
+
# see `prefixed_working_directory` comments for more details
|
|
106
|
+
return self.team_id
|
|
107
|
+
else
|
|
108
|
+
spaceship = SpaceshipEnsure.new(self.username, self.team_id, self.team_name)
|
|
109
|
+
return spaceship.team_id
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def prefixed_working_directory
|
|
114
|
+
# We fall back to "*", which means certificates and profiles
|
|
115
|
+
# from all teams that use this bucket would be installed. This is not ideal, but
|
|
116
|
+
# unless the user provides a `team_id`, we can't know which one to use
|
|
117
|
+
# This only happens if `readonly` is activated, and no `team_id` was provided
|
|
118
|
+
@_folder_prefix ||= currently_used_team_id
|
|
119
|
+
if @_folder_prefix.nil?
|
|
120
|
+
# We use a `@_folder_prefix` variable, to keep state between multiple calls of this
|
|
121
|
+
# method, as the value won't change. This way the warning is only printed once
|
|
122
|
+
UI.important("Looks like you run `match` in `readonly` mode, and didn't provide a `team_id`. This will still work, however it is recommended to provide a `team_id` in your Appfile or Matchfile")
|
|
123
|
+
@_folder_prefix = "*"
|
|
124
|
+
end
|
|
125
|
+
return File.join(working_directory, @_folder_prefix)
|
|
126
|
+
end
|
|
127
|
+
|
|
84
128
|
def download
|
|
85
129
|
# Check if we already have a functional working_directory
|
|
86
130
|
return if @working_directory
|
|
@@ -8,6 +8,11 @@ module Match
|
|
|
8
8
|
# and decrypt/encrypt them
|
|
9
9
|
attr_accessor :working_directory
|
|
10
10
|
|
|
11
|
+
# To make debugging easier, we have a custom exception here
|
|
12
|
+
def prefixed_working_directory
|
|
13
|
+
not_implemented(__method__)
|
|
14
|
+
end
|
|
15
|
+
|
|
11
16
|
# To make debugging easier, we have a custom exception here
|
|
12
17
|
def working_directory
|
|
13
18
|
if @working_directory.nil?
|
metadata
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fastlane
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.128.0
|
|
4
|
+
version: 2.128.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
- Danielle Tomlinson
|
|
8
|
-
- Joshua Liebowitz
|
|
9
|
-
- Andrew McBurney
|
|
10
|
-
- Jimmy Dee
|
|
11
|
-
- Jorge Revuelta H
|
|
12
|
-
- Josh Holtz
|
|
13
7
|
- Helmut Januschka
|
|
14
|
-
- Jan Piotrowski
|
|
15
|
-
- Aaron Brager
|
|
16
8
|
- Kohki Miki
|
|
17
|
-
-
|
|
9
|
+
- Jimmy Dee
|
|
10
|
+
- Josh Holtz
|
|
18
11
|
- Fumiya Nakamura
|
|
19
12
|
- Jérôme Lacoste
|
|
20
|
-
-
|
|
13
|
+
- Danielle Tomlinson
|
|
14
|
+
- Matthew Ellis
|
|
21
15
|
- Felix Krause
|
|
16
|
+
- Maksym Grebenets
|
|
17
|
+
- Joshua Liebowitz
|
|
18
|
+
- Stefan Natchev
|
|
22
19
|
- Luka Mirosevic
|
|
20
|
+
- Jorge Revuelta H
|
|
21
|
+
- Andrew McBurney
|
|
23
22
|
- Olivier Halligon
|
|
24
|
-
- Stefan Natchev
|
|
25
|
-
- Maksym Grebenets
|
|
26
23
|
- Iulian Onofrei
|
|
24
|
+
- Aaron Brager
|
|
25
|
+
- Jan Piotrowski
|
|
26
|
+
- Manu Wallner
|
|
27
27
|
autorequire:
|
|
28
28
|
bindir: bin
|
|
29
29
|
cert_chain: []
|
|
@@ -1441,6 +1441,7 @@ files:
|
|
|
1441
1441
|
- match/lib/match/encryption/interface.rb
|
|
1442
1442
|
- match/lib/match/encryption/openssl.rb
|
|
1443
1443
|
- match/lib/match/generator.rb
|
|
1444
|
+
- match/lib/match/importer.rb
|
|
1444
1445
|
- match/lib/match/migrate.rb
|
|
1445
1446
|
- match/lib/match/module.rb
|
|
1446
1447
|
- match/lib/match/nuke.rb
|
|
@@ -1741,24 +1742,24 @@ metadata:
|
|
|
1741
1742
|
post_install_message:
|
|
1742
1743
|
rdoc_options: []
|
|
1743
1744
|
require_paths:
|
|
1744
|
-
-
|
|
1745
|
-
-
|
|
1746
|
-
- sigh/lib
|
|
1747
|
-
- fastlane_core/lib
|
|
1748
|
-
- supply/lib
|
|
1749
|
-
- gym/lib
|
|
1750
|
-
- screengrab/lib
|
|
1751
|
-
- match/lib
|
|
1752
|
-
- frameit/lib
|
|
1745
|
+
- credentials_manager/lib
|
|
1746
|
+
- pem/lib
|
|
1753
1747
|
- snapshot/lib
|
|
1748
|
+
- frameit/lib
|
|
1749
|
+
- match/lib
|
|
1750
|
+
- fastlane_core/lib
|
|
1754
1751
|
- deliver/lib
|
|
1755
1752
|
- scan/lib
|
|
1753
|
+
- supply/lib
|
|
1756
1754
|
- cert/lib
|
|
1757
|
-
-
|
|
1758
|
-
-
|
|
1755
|
+
- fastlane/lib
|
|
1756
|
+
- spaceship/lib
|
|
1759
1757
|
- pilot/lib
|
|
1758
|
+
- gym/lib
|
|
1759
|
+
- precheck/lib
|
|
1760
|
+
- screengrab/lib
|
|
1761
|
+
- sigh/lib
|
|
1760
1762
|
- produce/lib
|
|
1761
|
-
- credentials_manager/lib
|
|
1762
1763
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
1763
1764
|
requirements:
|
|
1764
1765
|
- - ">="
|
|
@@ -1766,12 +1767,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
1766
1767
|
version: 2.0.0
|
|
1767
1768
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1768
1769
|
requirements:
|
|
1769
|
-
- - "
|
|
1770
|
+
- - ">="
|
|
1770
1771
|
- !ruby/object:Gem::Version
|
|
1771
|
-
version:
|
|
1772
|
+
version: '0'
|
|
1772
1773
|
requirements: []
|
|
1773
|
-
|
|
1774
|
-
rubygems_version: 2.6.8
|
|
1774
|
+
rubygems_version: 3.0.1
|
|
1775
1775
|
signing_key:
|
|
1776
1776
|
specification_version: 4
|
|
1777
1777
|
summary: The easiest way to automate beta deployments and releases for your iOS and
|