fastlane 2.212.2 → 2.214.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +94 -94
  3. data/deliver/lib/deliver/upload_price_tier.rb +1 -1
  4. data/fastlane/lib/assets/custom_action_template.rb +18 -12
  5. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +5 -3
  6. data/fastlane/lib/fastlane/actions/download_universal_apk_from_google_play.rb +124 -0
  7. data/fastlane/lib/fastlane/actions/ensure_git_status_clean.rb +31 -3
  8. data/fastlane/lib/fastlane/version.rb +1 -1
  9. data/fastlane/swift/Deliverfile.swift +1 -1
  10. data/fastlane/swift/DeliverfileProtocol.swift +1 -1
  11. data/fastlane/swift/Fastlane.swift +85 -6
  12. data/fastlane/swift/Gymfile.swift +1 -1
  13. data/fastlane/swift/GymfileProtocol.swift +1 -1
  14. data/fastlane/swift/Matchfile.swift +1 -1
  15. data/fastlane/swift/MatchfileProtocol.swift +5 -1
  16. data/fastlane/swift/Precheckfile.swift +1 -1
  17. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  18. data/fastlane/swift/Scanfile.swift +1 -1
  19. data/fastlane/swift/ScanfileProtocol.swift +5 -1
  20. data/fastlane/swift/Screengrabfile.swift +1 -1
  21. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  22. data/fastlane/swift/Snapshotfile.swift +1 -1
  23. data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
  24. data/fastlane/swift/formatting/Brewfile.lock.json +18 -18
  25. data/fastlane_core/lib/fastlane_core/cert_checker.rb +0 -5
  26. data/gym/lib/gym/generators/build_command_generator.rb +1 -1
  27. data/match/lib/match/importer.rb +1 -0
  28. data/match/lib/match/nuke.rb +1 -0
  29. data/match/lib/match/options.rb +5 -0
  30. data/match/lib/match/runner.rb +1 -0
  31. data/match/lib/match/storage/gitlab/client.rb +40 -14
  32. data/match/lib/match/storage/gitlab_secure_files.rb +17 -6
  33. data/pilot/lib/pilot/build_manager.rb +1 -1
  34. data/scan/lib/scan/detect_values.rb +8 -1
  35. data/scan/lib/scan/options.rb +5 -0
  36. data/scan/lib/scan/test_command_generator.rb +1 -1
  37. data/snapshot/lib/snapshot/test_command_generator.rb +1 -1
  38. data/spaceship/lib/spaceship/client.rb +0 -1
  39. data/spaceship/lib/spaceship/connect_api/models/user.rb +38 -0
  40. data/spaceship/lib/spaceship/connect_api/models/user_invitation.rb +5 -15
  41. data/spaceship/lib/spaceship/connect_api/users/users.rb +34 -0
  42. data/supply/lib/supply/client.rb +33 -0
  43. data/supply/lib/supply/generated_universal_apk.rb +24 -0
  44. data/supply/lib/supply.rb +1 -0
  45. metadata +30 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 698222da63360e54a4d41e791a7ab1b2ac9331b348ef8626831d61a7261872de
4
- data.tar.gz: c89309b1a27610bd6f51dfad0b471ac908bbec30e981edf7b56485e5f83738f4
3
+ metadata.gz: c90da076e95e7d56aeb37df6dbd0f85ea6163ae1833e0ed048cb8e324c52b695
4
+ data.tar.gz: e0e11ef5984ec45bf0a8ac71b6ea2b635f5fe6f4e2f8244b6d701cee32d842c2
5
5
  SHA512:
6
- metadata.gz: fc46b26354a94f87f630a434fcb0f8387f9d84661da4b01aa9ea72f565a97f864d6fb6f2124a7a9342ae91c3f3c59657452f99c255bf0c418ae5da33d821af32
7
- data.tar.gz: 7198cdb4e60bf1c3c5b495307306a2888be696dd924a0e63aae7d787bdbfa5b4468d8a7f661f8fc741b79740801efcc603b32f912d9940a35373ec7230da5bd3
6
+ metadata.gz: 673b9f22b71d12323220280d414c45ba8b7c537b2b9c91c38ee9a46f9b7b4f7053c7fe0f9cc6583e4414608f3b755a154211e3b30ee202aeb59b282045ffb924
7
+ data.tar.gz: d8644326864b6f6895fd6c55a4ebc503cc2f730eb0dfce45201bab4bb4d8658b655e1746452d549793d47b234d2a8a8f7aad0c8bf246c7f46a8155eb556f5bde
data/README.md CHANGED
@@ -35,17 +35,43 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
35
35
  <!-- This table is regenerated and resorted on each release -->
36
36
  <table id='team'>
37
37
  <tr>
38
- <td id='maksym-grebenets'>
39
- <a href='https://github.com/mgrebenets'>
40
- <img src='https://github.com/mgrebenets.png' width='140px;'>
38
+ <td id='jorge-revuelta-h'>
39
+ <a href='https://github.com/minuscorp'>
40
+ <img src='https://github.com/minuscorp.png' width='140px;'>
41
41
  </a>
42
- <h4 align='center'><a href='https://twitter.com/mgrebenets'>Maksym Grebenets</a></h4>
42
+ <h4 align='center'><a href='https://twitter.com/minuscorp'>Jorge Revuelta H</a></h4>
43
43
  </td>
44
- <td id='iulian-onofrei'>
45
- <a href='https://github.com/revolter'>
46
- <img src='https://github.com/revolter.png' width='140px;'>
44
+ <td id='danielle-tomlinson'>
45
+ <a href='https://github.com/endocrimes'>
46
+ <img src='https://github.com/endocrimes.png' width='140px;'>
47
47
  </a>
48
- <h4 align='center'><a href='https://twitter.com/Revolt666'>Iulian Onofrei</a></h4>
48
+ <h4 align='center'><a href='https://twitter.com/endocrimes'>Danielle Tomlinson</a></h4>
49
+ </td>
50
+ <td id='jan-piotrowski'>
51
+ <a href='https://github.com/janpio'>
52
+ <img src='https://github.com/janpio.png' width='140px;'>
53
+ </a>
54
+ <h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
55
+ </td>
56
+ <td id='manish-rathi'>
57
+ <a href='https://github.com/crazymanish'>
58
+ <img src='https://github.com/crazymanish.png' width='140px;'>
59
+ </a>
60
+ <h4 align='center'><a href='https://twitter.com/iammanishrathi'>Manish Rathi</a></h4>
61
+ </td>
62
+ <td id='helmut-januschka'>
63
+ <a href='https://github.com/hjanuschka'>
64
+ <img src='https://github.com/hjanuschka.png' width='140px;'>
65
+ </a>
66
+ <h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
67
+ </td>
68
+ </tr>
69
+ <tr>
70
+ <td id='roger-oba'>
71
+ <a href='https://github.com/rogerluan'>
72
+ <img src='https://github.com/rogerluan.png' width='140px;'>
73
+ </a>
74
+ <h4 align='center'><a href='https://twitter.com/rogerluan_'>Roger Oba</a></h4>
49
75
  </td>
50
76
  <td id='josh-holtz'>
51
77
  <a href='https://github.com/joshdholtz'>
@@ -53,63 +79,63 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
53
79
  </a>
54
80
  <h4 align='center'><a href='https://twitter.com/joshdholtz'>Josh Holtz</a></h4>
55
81
  </td>
56
- <td id='max-ott'>
57
- <a href='https://github.com/max-ott'>
58
- <img src='https://github.com/max-ott.png' width='140px;'>
82
+ <td id='iulian-onofrei'>
83
+ <a href='https://github.com/revolter'>
84
+ <img src='https://github.com/revolter.png' width='140px;'>
59
85
  </a>
60
- <h4 align='center'><a href='https://twitter.com/ott_max'>Max Ott</a></h4>
86
+ <h4 align='center'><a href='https://twitter.com/Revolt666'>Iulian Onofrei</a></h4>
61
87
  </td>
62
- <td id='olivier-halligon'>
63
- <a href='https://github.com/AliSoftware'>
64
- <img src='https://github.com/AliSoftware.png' width='140px;'>
88
+ <td id='felix-krause'>
89
+ <a href='https://github.com/KrauseFx'>
90
+ <img src='https://github.com/KrauseFx.png' width='140px;'>
65
91
  </a>
66
- <h4 align='center'><a href='https://twitter.com/aligatr'>Olivier Halligon</a></h4>
92
+ <h4 align='center'><a href='https://twitter.com/KrauseFx'>Felix Krause</a></h4>
93
+ </td>
94
+ <td id='jérôme-lacoste'>
95
+ <a href='https://github.com/lacostej'>
96
+ <img src='https://github.com/lacostej.png' width='140px;'>
97
+ </a>
98
+ <h4 align='center'><a href='https://twitter.com/lacostej'>Jérôme Lacoste</a></h4>
67
99
  </td>
68
100
  </tr>
69
101
  <tr>
70
- <td id='matthew-ellis'>
71
- <a href='https://github.com/matthewellis'>
72
- <img src='https://github.com/matthewellis.png' width='140px;'>
102
+ <td id='jimmy-dee'>
103
+ <a href='https://github.com/jdee'>
104
+ <img src='https://github.com/jdee.png' width='140px;'>
73
105
  </a>
74
- <h4 align='center'><a href='https://twitter.com/mellis1995'>Matthew Ellis</a></h4>
106
+ <h4 align='center'>Jimmy Dee</h4>
75
107
  </td>
76
- <td id='helmut-januschka'>
77
- <a href='https://github.com/hjanuschka'>
78
- <img src='https://github.com/hjanuschka.png' width='140px;'>
108
+ <td id='joshua-liebowitz'>
109
+ <a href='https://github.com/taquitos'>
110
+ <img src='https://github.com/taquitos.png' width='140px;'>
79
111
  </a>
80
- <h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
112
+ <h4 align='center'><a href='https://twitter.com/taquitos'>Joshua Liebowitz</a></h4>
81
113
  </td>
82
- <td id='luka-mirosevic'>
83
- <a href='https://github.com/lmirosevic'>
84
- <img src='https://github.com/lmirosevic.png' width='140px;'>
114
+ <td id='max-ott'>
115
+ <a href='https://github.com/max-ott'>
116
+ <img src='https://github.com/max-ott.png' width='140px;'>
85
117
  </a>
86
- <h4 align='center'><a href='https://twitter.com/lmirosevic'>Luka Mirosevic</a></h4>
118
+ <h4 align='center'><a href='https://twitter.com/ott_max'>Max Ott</a></h4>
87
119
  </td>
88
- <td id='roger-oba'>
89
- <a href='https://github.com/rogerluan'>
90
- <img src='https://github.com/rogerluan.png' width='140px;'>
120
+ <td id='andrew-mcburney'>
121
+ <a href='https://github.com/armcburney'>
122
+ <img src='https://github.com/armcburney.png' width='140px;'>
91
123
  </a>
92
- <h4 align='center'><a href='https://twitter.com/rogerluan_'>Roger Oba</a></h4>
124
+ <h4 align='center'><a href='https://twitter.com/armcburney'>Andrew McBurney</a></h4>
93
125
  </td>
94
- <td id='łukasz-grabowski'>
95
- <a href='https://github.com/lucgrabowski'>
96
- <img src='https://github.com/lucgrabowski.png' width='140px;'>
126
+ <td id='satoshi-namai'>
127
+ <a href='https://github.com/ainame'>
128
+ <img src='https://github.com/ainame.png' width='140px;'>
97
129
  </a>
98
- <h4 align='center'>Łukasz Grabowski</h4>
130
+ <h4 align='center'><a href='https://twitter.com/ainame'>Satoshi Namai</a></h4>
99
131
  </td>
100
132
  </tr>
101
133
  <tr>
102
- <td id='jan-piotrowski'>
103
- <a href='https://github.com/janpio'>
104
- <img src='https://github.com/janpio.png' width='140px;'>
105
- </a>
106
- <h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
107
- </td>
108
- <td id='kohki-miki'>
109
- <a href='https://github.com/giginet'>
110
- <img src='https://github.com/giginet.png' width='140px;'>
134
+ <td id='maksym-grebenets'>
135
+ <a href='https://github.com/mgrebenets'>
136
+ <img src='https://github.com/mgrebenets.png' width='140px;'>
111
137
  </a>
112
- <h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
138
+ <h4 align='center'><a href='https://twitter.com/mgrebenets'>Maksym Grebenets</a></h4>
113
139
  </td>
114
140
  <td id='aaron-brager'>
115
141
  <a href='https://github.com/getaaron'>
@@ -123,19 +149,11 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
123
149
  </a>
124
150
  <h4 align='center'><a href='https://twitter.com/mollyIV'>Daniel Jankowski</a></h4>
125
151
  </td>
126
- <td id='jorge-revuelta-h'>
127
- <a href='https://github.com/minuscorp'>
128
- <img src='https://github.com/minuscorp.png' width='140px;'>
129
- </a>
130
- <h4 align='center'><a href='https://twitter.com/minuscorp'>Jorge Revuelta H</a></h4>
131
- </td>
132
- </tr>
133
- <tr>
134
- <td id='danielle-tomlinson'>
135
- <a href='https://github.com/endocrimes'>
136
- <img src='https://github.com/endocrimes.png' width='140px;'>
152
+ <td id='luka-mirosevic'>
153
+ <a href='https://github.com/lmirosevic'>
154
+ <img src='https://github.com/lmirosevic.png' width='140px;'>
137
155
  </a>
138
- <h4 align='center'><a href='https://twitter.com/endocrimes'>Danielle Tomlinson</a></h4>
156
+ <h4 align='center'><a href='https://twitter.com/lmirosevic'>Luka Mirosevic</a></h4>
139
157
  </td>
140
158
  <td id='fumiya-nakamura'>
141
159
  <a href='https://github.com/nafu'>
@@ -143,17 +161,13 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
143
161
  </a>
144
162
  <h4 align='center'><a href='https://twitter.com/nafu003'>Fumiya Nakamura</a></h4>
145
163
  </td>
146
- <td id='felix-krause'>
147
- <a href='https://github.com/KrauseFx'>
148
- <img src='https://github.com/KrauseFx.png' width='140px;'>
149
- </a>
150
- <h4 align='center'><a href='https://twitter.com/KrauseFx'>Felix Krause</a></h4>
151
- </td>
152
- <td id='satoshi-namai'>
153
- <a href='https://github.com/ainame'>
154
- <img src='https://github.com/ainame.png' width='140px;'>
164
+ </tr>
165
+ <tr>
166
+ <td id='kohki-miki'>
167
+ <a href='https://github.com/giginet'>
168
+ <img src='https://github.com/giginet.png' width='140px;'>
155
169
  </a>
156
- <h4 align='center'><a href='https://twitter.com/ainame'>Satoshi Namai</a></h4>
170
+ <h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
157
171
  </td>
158
172
  <td id='stefan-natchev'>
159
173
  <a href='https://github.com/snatchev'>
@@ -161,13 +175,11 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
161
175
  </a>
162
176
  <h4 align='center'><a href='https://twitter.com/snatchev'>Stefan Natchev</a></h4>
163
177
  </td>
164
- </tr>
165
- <tr>
166
- <td id='jimmy-dee'>
167
- <a href='https://github.com/jdee'>
168
- <img src='https://github.com/jdee.png' width='140px;'>
178
+ <td id='matthew-ellis'>
179
+ <a href='https://github.com/matthewellis'>
180
+ <img src='https://github.com/matthewellis.png' width='140px;'>
169
181
  </a>
170
- <h4 align='center'>Jimmy Dee</h4>
182
+ <h4 align='center'><a href='https://twitter.com/mellis1995'>Matthew Ellis</a></h4>
171
183
  </td>
172
184
  <td id='manu-wallner'>
173
185
  <a href='https://github.com/milch'>
@@ -175,31 +187,19 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
175
187
  </a>
176
188
  <h4 align='center'><a href='https://twitter.com/acrooow'>Manu Wallner</a></h4>
177
189
  </td>
178
- <td id='jérôme-lacoste'>
179
- <a href='https://github.com/lacostej'>
180
- <img src='https://github.com/lacostej.png' width='140px;'>
181
- </a>
182
- <h4 align='center'><a href='https://twitter.com/lacostej'>Jérôme Lacoste</a></h4>
183
- </td>
184
- <td id='manish-rathi'>
185
- <a href='https://github.com/crazymanish'>
186
- <img src='https://github.com/crazymanish.png' width='140px;'>
187
- </a>
188
- <h4 align='center'><a href='https://twitter.com/iammanishrathi'>Manish Rathi</a></h4>
189
- </td>
190
- <td id='joshua-liebowitz'>
191
- <a href='https://github.com/taquitos'>
192
- <img src='https://github.com/taquitos.png' width='140px;'>
190
+ <td id='olivier-halligon'>
191
+ <a href='https://github.com/AliSoftware'>
192
+ <img src='https://github.com/AliSoftware.png' width='140px;'>
193
193
  </a>
194
- <h4 align='center'><a href='https://twitter.com/taquitos'>Joshua Liebowitz</a></h4>
194
+ <h4 align='center'><a href='https://twitter.com/aligatr'>Olivier Halligon</a></h4>
195
195
  </td>
196
196
  </tr>
197
197
  <tr>
198
- <td id='andrew-mcburney'>
199
- <a href='https://github.com/armcburney'>
200
- <img src='https://github.com/armcburney.png' width='140px;'>
198
+ <td id='łukasz-grabowski'>
199
+ <a href='https://github.com/lucgrabowski'>
200
+ <img src='https://github.com/lucgrabowski.png' width='140px;'>
201
201
  </a>
202
- <h4 align='center'><a href='https://twitter.com/armcburney'>Andrew McBurney</a></h4>
202
+ <h4 align='center'>Łukasz Grabowski</h4>
203
203
  </td>
204
204
  </table>
205
205
 
@@ -21,7 +21,7 @@ module Deliver
21
21
  # Need to get prices from the app's relationships
22
22
  # Prices from app's relationship doess not have price tier so need to fetch app price with price tier relationship
23
23
  app_prices = app.prices
24
- if app_prices.first
24
+ if app_prices&.first
25
25
  app_price = Spaceship::ConnectAPI.get_app_price(app_price_id: app_prices.first.id, includes: "priceTier").first
26
26
  old_price = app_price.price_tier.id
27
27
  else
@@ -7,7 +7,7 @@ module Fastlane
7
7
  class [[NAME_CLASS]] < Action
8
8
  def self.run(params)
9
9
  # fastlane will take care of reading in the parameter and fetching the environment variable:
10
- UI.message "Parameter API Token: #{params[:api_token]}"
10
+ UI.message("Parameter API Token: #{params[:api_token]}")
11
11
 
12
12
  # sh "shellcommand ./path"
13
13
 
@@ -19,13 +19,13 @@ module Fastlane
19
19
  #####################################################
20
20
 
21
21
  def self.description
22
- "A short description with <= 80 characters of what this action does"
22
+ 'A short description with <= 80 characters of what this action does'
23
23
  end
24
24
 
25
25
  def self.details
26
26
  # Optional:
27
27
  # this is your chance to provide a more detailed description of this action
28
- "You can use this action to do cool things..."
28
+ 'You can use this action to do cool things...'
29
29
  end
30
30
 
31
31
  def self.available_options
@@ -34,17 +34,23 @@ module Fastlane
34
34
  # Below a few examples
35
35
  [
36
36
  FastlaneCore::ConfigItem.new(key: :api_token,
37
- env_name: "FL_[[NAME_UP]]_API_TOKEN", # The name of the environment variable
38
- description: "API Token for [[NAME_CLASS]]", # a short description of this parameter
37
+ # The name of the environment variable
38
+ env_name: 'FL_[[NAME_UP]]_API_TOKEN',
39
+ # a short description of this parameter
40
+ description: 'API Token for [[NAME_CLASS]]',
39
41
  verify_block: proc do |value|
40
- UI.user_error!("No API token for [[NAME_CLASS]] given, pass using `api_token: 'token'`") unless (value and not value.empty?)
41
- # UI.user_error!("Couldn't find file at path '#{value}'") unless File.exist?(value)
42
+ unless value && !value.empty?
43
+ UI.user_error!("No API token for [[NAME_CLASS]] given, pass using `api_token: 'token'`")
44
+ end
45
+ # UI.user_error!("Couldn't find file at path '#{value}'") unless File.exist?(value)
42
46
  end),
43
47
  FastlaneCore::ConfigItem.new(key: :development,
44
- env_name: "FL_[[NAME_UP]]_DEVELOPMENT",
45
- description: "Create a development certificate instead of a distribution one",
46
- is_string: false, # true: verifies the input is a string, false: every kind of value
47
- default_value: false) # the default value if the user didn't provide one
48
+ env_name: 'FL_[[NAME_UP]]_DEVELOPMENT',
49
+ description: 'Create a development certificate instead of a distribution one',
50
+ # true: verifies the input is a string, false: every kind of value
51
+ is_string: false,
52
+ # the default value if the user didn't provide one
53
+ default_value: false)
48
54
  ]
49
55
  end
50
56
 
@@ -62,7 +68,7 @@ module Fastlane
62
68
 
63
69
  def self.authors
64
70
  # So no one will ever forget your contribution to fastlane :) You are awesome btw!
65
- ["Your GitHub/Twitter Name"]
71
+ ['Your GitHub/Twitter Name']
66
72
  end
67
73
 
68
74
  def self.is_supported?(platform)
@@ -212,7 +212,7 @@ fastlane match development
212
212
 
213
213
  <img src="/img/actions/match_appstore_small.gif" width="550" />
214
214
 
215
- This will create a new certificate and provisioning profile (if required) and store them in your selected storage.
215
+ This will create a new certificate and provisioning profile (if required) and store them in your selected storage.
216
216
  If you previously ran _match_ with the configured storage it will automatically install the existing profiles from your storage.
217
217
 
218
218
  The provisioning profiles are installed in `~/Library/MobileDevice/Provisioning Profiles` while the certificates and private keys are installed in your Keychain.
@@ -400,7 +400,7 @@ By using the `force_for_new_devices` parameter, _match_ will check if the (enabl
400
400
 
401
401
  _**Important:** The `force_for_new_devices` parameter is ignored for App Store provisioning profiles since they don't contain any device information._
402
402
 
403
- If you're not using _fastlane_, you can also use the `force_for_new_devices` option from the command line:
403
+ If you're not using `Fastfile`, you can also use the `force_for_new_devices` option from the command line:
404
404
 
405
405
  ```no-highlight
406
406
  fastlane match adhoc --force_for_new_devices
@@ -512,9 +512,11 @@ Please be careful when using this option and ensure the certificates and profile
512
512
  If you want to manually decrypt a file you can.
513
513
 
514
514
  ```no-highlight
515
- openssl aes-256-cbc -k "<password>" -in "<fileYouWantToDecryptPath>" -out "<decryptedFilePath>" -a -d
515
+ openssl aes-256-cbc -k "<password>" -in "<fileYouWantToDecryptPath>" -out "<decryptedFilePath>" -a -d -md [md5|sha256]
516
516
  ```
517
517
 
518
+ _**Note:** You may need to swap double quotes `"` for single quotes `'` if your match password contains an exclamation mark `!`._
519
+
518
520
  #### Export Distribution Certificate and Private Key as Single .p12 File
519
521
 
520
522
  _match_ stores the certificate (`.cer`) and the private key (`.p12`) files separately. The following steps will repackage the separate certificate and private key into a single `.p12` file.
@@ -0,0 +1,124 @@
1
+ require 'supply'
2
+ require 'supply/options'
3
+
4
+ module Fastlane
5
+ module Actions
6
+ class DownloadUniversalApkFromGooglePlayAction < Action
7
+ def self.run(params)
8
+ package_name = params[:package_name]
9
+ version_code = params[:version_code]
10
+ destination = params[:destination]
11
+ cert_sha = params[:certificate_sha256_hash]
12
+
13
+ client = Supply::Client.make_from_config(params: params)
14
+
15
+ UI.message("Fetching the list of generated APKs from the Google API...")
16
+ all_universal_apks = client.list_generated_universal_apks(package_name: package_name, version_code: version_code)
17
+ matching_apks = all_universal_apks.select { |apk| cert_sha.nil? || apk.certificate_sha256_hash&.casecmp?(cert_sha) }
18
+
19
+ all_certs_printable_list = all_universal_apks.map { |apk| " - #{apk.certificate_sha256_hash}" }
20
+ if matching_apks.count > 1
21
+ message = <<~ERROR
22
+ We found multiple Generated Universal APK, with the following `certificate_sha256_hash`:
23
+ #{all_certs_printable_list.join("\n")}
24
+
25
+ Use the `certificate_sha256_hash` parameter to specify which one to download.
26
+ ERROR
27
+ UI.user_error!(message)
28
+ elsif matching_apks.empty?
29
+ # NOTE: if no APK was found at all to begin with, the client would already have raised a user_error!('Google Api Error ...')
30
+ message = <<~ERROR
31
+ None of the Universal APK(s) found for this version code matched the `certificate_sha256_hash` of `#{cert_sha}`.
32
+
33
+ We found #{all_universal_apks.count} Generated Universal APK(s), but with a different `certificate_sha256_hash`:
34
+ #{all_certs_printable_list.join("\n")}
35
+ ERROR
36
+ UI.user_error!(message)
37
+ end
38
+
39
+ UI.message("Downloading Generated Universal APK to `#{destination}`...")
40
+ FileUtils.mkdir_p(File.dirname(destination))
41
+ client.download_generated_universal_apk(generated_universal_apk: matching_apks.first, destination: destination)
42
+
43
+ UI.success("Universal APK successfully downloaded to `#{destination}`.")
44
+ destination
45
+ end
46
+
47
+ #####################################################
48
+ # @!group Documentation
49
+ #####################################################
50
+
51
+ def self.description
52
+ "Download the Universal APK of a given version code from the Google Play Console"
53
+ end
54
+
55
+ def self.details
56
+ <<~DETAILS
57
+ Download the universal APK of a given version code from the Google Play Console.
58
+
59
+ This uses fastlane `Supply` (and the `AndroidPublisher` Google API) to download the Universal APK
60
+ generated by Google after you uploaded an `.aab` bundle to the Play Console.
61
+
62
+ See https://developers.google.com/android-publisher/api-ref/rest/v3/generatedapks/list
63
+ DETAILS
64
+ end
65
+
66
+ def self.available_options
67
+ # Only borrow _some_ of the ConfigItems from https://github.com/fastlane/fastlane/blob/master/supply/lib/supply/options.rb
68
+ # So we don't have to duplicate the name, env_var, type, description, and verify_block of those here.
69
+ supply_borrowed_options = Supply::Options.available_options.select do |o|
70
+ %i[package_name version_code json_key json_key_data root_url timeout].include?(o.key)
71
+ end
72
+ # Adjust the description for the :version_code ConfigItem for our action's use case
73
+ supply_borrowed_options.find { |o| o.key == :version_code }&.description = "The versionCode for which to download the generated APK"
74
+
75
+ [
76
+ *supply_borrowed_options,
77
+
78
+ # The remaining ConfigItems below are specific to this action
79
+ FastlaneCore::ConfigItem.new(key: :destination,
80
+ env_name: 'DOWNLOAD_UNIVERSAL_APK_DESTINATION',
81
+ optional: false,
82
+ type: String,
83
+ description: "The path on disk where to download the Generated Universal APK",
84
+ verify_block: proc do |value|
85
+ UI.user_error!("The 'destination' must be a file path with the `.apk` file extension") unless File.extname(value) == '.apk'
86
+ end),
87
+ FastlaneCore::ConfigItem.new(key: :certificate_sha256_hash,
88
+ env_name: 'DOWNLOAD_UNIVERSAL_APK_CERTIFICATE_SHA256_HASH',
89
+ optional: true,
90
+ type: String,
91
+ description: "The SHA256 hash of the signing key for which to download the Universal, Code-Signed APK for. " \
92
+ + "Use 'xx:xx:xx:…' format (32 hex bytes separated by colons), as printed by `keytool -list -keystore <keystorefile>`. " \
93
+ + "Only useful to provide if you have multiple signing keys configured on GPC, to specify which generated APK to download",
94
+ verify_block: proc do |value|
95
+ bytes = value.split(':')
96
+ next if bytes.length == 32 && bytes.all? { |byte| /^[0-9a-fA-F]{2}$/.match?(byte) }
97
+
98
+ UI.user_error!("When provided, the certificate sha256 must be in the 'xx:xx:xx:…:xx' (32 hex bytes separated by colons) format")
99
+ end)
100
+ ]
101
+ end
102
+
103
+ def self.output
104
+ # Define the shared values you are going to provide
105
+ end
106
+
107
+ def self.return_value
108
+ 'The path to the downloaded Universal APK. The action will raise an exception if it failed to find or download the APK in Google Play'
109
+ end
110
+
111
+ def self.authors
112
+ ['Automattic']
113
+ end
114
+
115
+ def self.category
116
+ :production
117
+ end
118
+
119
+ def self.is_supported?(platform)
120
+ platform == :android
121
+ end
122
+ end
123
+ end
124
+ end
@@ -7,12 +7,35 @@ module Fastlane
7
7
  # Raises an exception and stop the lane execution if the repo is not in a clean state
8
8
  class EnsureGitStatusCleanAction < Action
9
9
  def self.run(params)
10
+ # Build command
10
11
  if params[:ignored]
11
12
  ignored_mode = params[:ignored]
12
13
  ignored_mode = 'no' if ignored_mode == 'none'
13
- repo_status = Actions.sh("git status --porcelain --ignored='#{ignored_mode}'")
14
+ command = "git status --porcelain --ignored='#{ignored_mode}'"
14
15
  else
15
- repo_status = Actions.sh("git status --porcelain")
16
+ command = "git status --porcelain"
17
+ end
18
+
19
+ # Don't log if manually ignoring files as it will emulate output later
20
+ print_output = params[:ignore_files].nil?
21
+ repo_status = Actions.sh(command, log: print_output)
22
+
23
+ # Manual post processing trying to ignore certain file paths
24
+ if (ignore_files = params[:ignore_files])
25
+ repo_status = repo_status.lines.reject do |line|
26
+ path = line.split(' ').last
27
+ was_found = ignore_files.include?(path)
28
+
29
+ UI.message("Ignoring '#{path}'") if was_found
30
+
31
+ was_found
32
+ end.join("")
33
+
34
+ # Emulate the output format of `git status --porcelain`
35
+ UI.command(command)
36
+ repo_status.lines.each do |line|
37
+ UI.message("▸ " + line.chomp.magenta)
38
+ end
16
39
  end
17
40
 
18
41
  repo_clean = repo_status.empty?
@@ -86,7 +109,12 @@ module Fastlane
86
109
  modes = %w(traditional none matching)
87
110
 
88
111
  UI.user_error!("Unsupported mode, must be: #{modes}") unless modes.include?(mode)
89
- end)
112
+ end),
113
+ FastlaneCore::ConfigItem.new(key: :ignore_files,
114
+ env_name: "FL_ENSURE_GIT_STATUS_CLEAN_IGNORE_FILES",
115
+ description: "Array of files to ignore",
116
+ optional: true,
117
+ type: Array)
90
118
  ]
91
119
  end
92
120
 
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
- VERSION = '2.212.2'.freeze
2
+ VERSION = '2.214.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 = '1.12.1'.freeze
@@ -17,4 +17,4 @@ public class Deliverfile: DeliverfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.212.2
20
+ // Generated with fastlane 2.214.0
@@ -264,4 +264,4 @@ public extension DeliverfileProtocol {
264
264
 
265
265
  // Please don't remove the lines below
266
266
  // They are used to detect outdated files
267
- // FastlaneRunnerAPIVersion [0.9.115]
267
+ // FastlaneRunnerAPIVersion [0.9.117]