fastlane 2.128.0.beta.20190722200021 → 2.128.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|