deliver 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +51 -66
- data/bin/deliver +2 -6
- data/lib/assets/DeliverfileDefault +9 -5
- data/lib/assets/DeliverfileExample +10 -11
- data/lib/deliver.rb +4 -2
- data/lib/deliver/app_metadata.rb +11 -3
- data/lib/deliver/commands/init.rb +0 -2
- data/lib/deliver/commands/run.rb +11 -10
- data/lib/deliver/deliver_process.rb +17 -24
- data/lib/deliver/deliverfile/deliverfile.rb +1 -1
- data/lib/deliver/deliverfile/deliverfile_creator.rb +7 -4
- data/lib/deliver/deliverfile/dsl.rb +2 -1
- data/lib/deliver/dependency_checker.rb +1 -0
- data/lib/deliver/helper.rb +5 -0
- data/lib/deliver/ipa_uploader.rb +1 -3
- data/lib/deliver/itunes_connect.rb +40 -24
- data/lib/deliver/itunes_transporter.rb +9 -6
- data/lib/deliver/update_checker.rb +1 -1
- data/lib/deliver/version.rb +1 -1
- metadata +9 -28
- data/lib/deliver/password_manager.rb +0 -110
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 221e6f16252aa538e403f17cdf318edb2dd6ea20
|
4
|
+
data.tar.gz: fb4058c128cc42e5f871714c41c23b521949557e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 860cdd383422e8e531c73db2bc549d2a56d8db91465275b3c4266746fad5cb2dd7e65b870adf71f81aac5abfe18c387ec76b6905362b697cf725bb3dab8beb6e
|
7
|
+
data.tar.gz: a76927b8bbbcf2b4f63b1a10410f0b55d82c96d6a130d8eb124ed7a345b1ae462d0f6753e4cb0357ef001752c67b56761cd8e68f812d340e6b492d5729d37620
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,16 @@
|
|
1
|
+
<h3 align="center">
|
2
|
+
<a href="https://github.com/KrauseFx/fastlane">
|
3
|
+
<img src="assets/fastlane.png" width="150" />
|
4
|
+
<br />
|
5
|
+
fastlane
|
6
|
+
</a>
|
7
|
+
</h3>
|
1
8
|
<p align="center">
|
2
|
-
<b>
|
3
|
-
<a href="https://github.com/KrauseFx/snapshot">
|
4
|
-
<a href="https://github.com/KrauseFx/frameit">
|
5
|
-
<a href="https://github.com/KrauseFx/PEM">PEM</a> •
|
6
|
-
<a href="https://github.com/KrauseFx/sigh">
|
9
|
+
<b>deliver</b> •
|
10
|
+
<a href="https://github.com/KrauseFx/snapshot">snapshot</a> •
|
11
|
+
<a href="https://github.com/KrauseFx/frameit">frameit</a> •
|
12
|
+
<a href="https://github.com/KrauseFx/PEM">PEM</a> •
|
13
|
+
<a href="https://github.com/KrauseFx/sigh">sigh</a>
|
7
14
|
</p>
|
8
15
|
-------
|
9
16
|
|
@@ -11,7 +18,7 @@
|
|
11
18
|
<img src="assets/deliver.png">
|
12
19
|
</p>
|
13
20
|
|
14
|
-
|
21
|
+
deliver
|
15
22
|
============
|
16
23
|
|
17
24
|
[![Twitter: @KauseFx](https://img.shields.io/badge/contact-@KrauseFx-blue.svg?style=flat)](https://twitter.com/KrauseFx)
|
@@ -19,13 +26,11 @@ Deliver - Continuous Deployment for iOS
|
|
19
26
|
[![Gem](https://img.shields.io/gem/v/deliver.svg?style=flat)](http://rubygems.org/gems/deliver)
|
20
27
|
[![Build Status](https://img.shields.io/travis/KrauseFx/deliver/master.svg?style=flat)](https://travis-ci.org/KrauseFx/deliver)
|
21
28
|
|
29
|
+
###### Upload screenshots, metadata and your app to the App Store using a single command
|
22
30
|
|
23
|
-
|
24
|
-
whole process to start with Continuous Deployment.
|
31
|
+
`deliver` **can upload ipa files, app screenshots and more to the iTunes Connect backend**, which means, you can deploy new iPhone app updates using the command line.
|
25
32
|
|
26
|
-
|
27
|
-
|
28
|
-
Follow the developer on Twitter: [@KrauseFx](https://twitter.com/KrauseFx)
|
33
|
+
Get in contact with the developer on Twitter: [@KrauseFx](https://twitter.com/KrauseFx)
|
29
34
|
|
30
35
|
|
31
36
|
-------
|
@@ -34,22 +39,22 @@ Follow the developer on Twitter: [@KrauseFx](https://twitter.com/KrauseFx)
|
|
34
39
|
<a href="#installation">Installation</a> •
|
35
40
|
<a href="#quick-start">Quick Start</a> •
|
36
41
|
<a href="#usage">Usage</a> •
|
37
|
-
<a href="#
|
38
|
-
<a href="#can-i-trust-deliver">Can I trust Deliver?</a> •
|
42
|
+
<a href="#can-i-trust-deliver">Can I trust deliver?</a> •
|
39
43
|
<a href="#tips">Tips</a> •
|
40
44
|
<a href="#need-help">Need help?</a>
|
41
45
|
</p>
|
42
46
|
|
43
47
|
-------
|
44
48
|
|
49
|
+
<h5 align="center"><code>deliver</code> is part of <a href="http://fastlane.tools">fastlane</a>: connect all deployment tools into one streamlined workflow.</h5>
|
45
50
|
|
46
51
|
# Features
|
47
52
|
- Upload hundreds of screenshots with different languages from different devices
|
48
53
|
- Upload a new ipa file to iTunes Connect without Xcode from any computer
|
49
54
|
- Update app metadata
|
50
|
-
- Easily implement a real Continuous Deployment process
|
55
|
+
- Easily implement a real Continuous Deployment process using [fastlane](https://github.com/KrauseFx/fastlane)
|
51
56
|
- Store the configuration in git to easily deploy from **any** computer, including your Continuous Integration server (e.g. Jenkins)
|
52
|
-
- Get a PDF preview of the fetched metadata before uploading the app metadata and screenshots to Apple: [Example Preview](https://github.com/krausefx/deliver/blob/master/assets/PDFExample.png?raw=1)
|
57
|
+
- Get a PDF preview of the fetched metadata before uploading the app metadata and screenshots to Apple: [Example Preview](https://github.com/krausefx/deliver/blob/master/assets/PDFExample.png?raw=1)
|
53
58
|
- Automatically create new screenshots with [Snapshot](https://github.com/KrauseFx/snapshot)
|
54
59
|
|
55
60
|
# Installation
|
@@ -122,7 +127,11 @@ If you want to have the screenshots inside a device frame, with a background and
|
|
122
127
|
#### Upload a new ipa file with a changelog to the App Store
|
123
128
|
This will submit a new update to Apple
|
124
129
|
```ruby
|
125
|
-
ipa
|
130
|
+
ipa do
|
131
|
+
system("ipa build")
|
132
|
+
"./name.ipa"
|
133
|
+
end
|
134
|
+
|
126
135
|
changelog({
|
127
136
|
"en-US" => "This update adds cool new features",
|
128
137
|
"de-DE" => "Dieses Update ist super"
|
@@ -130,25 +139,33 @@ changelog({
|
|
130
139
|
```
|
131
140
|
If you wish to skip automated submission to review you can provide `--skip-deploy` option when calling `deliver`. This will upload the ipa file and app metadata, but will not submit the app for review.
|
132
141
|
|
142
|
+
The changelog is only used for App Store submission, not for TestFlight builds.
|
143
|
+
|
133
144
|
#### Upload a new ipa for TestFlight beta testers
|
134
145
|
|
135
146
|
In order to upload an `.ipa` file for Apple TestFlight you need to specify `beta_ipa` path in your `Deliverfile`
|
136
147
|
|
137
148
|
```ruby
|
138
|
-
beta_ipa
|
149
|
+
beta_ipa do
|
150
|
+
system("ipa build")
|
151
|
+
"./name.ipa"
|
152
|
+
end
|
139
153
|
```
|
140
154
|
|
141
155
|
and provide `--beta` option when calling `deliver`.
|
142
156
|
|
143
157
|
#### Implement blocks to run unit tests
|
158
|
+
If you're using [fastlane](http://github.com/krausefx/fastlane), run tests and error blocks there.
|
159
|
+
|
160
|
+
If you only use `deliver`, you can use the following blocks:
|
161
|
+
|
144
162
|
```ruby
|
145
163
|
unit_tests do
|
146
164
|
system("xctool test")
|
147
165
|
end
|
148
166
|
|
149
167
|
success do
|
150
|
-
|
151
|
-
notifier.ping "Successfully deployed new version"
|
168
|
+
system("Say 'success'")
|
152
169
|
end
|
153
170
|
|
154
171
|
error do |exception|
|
@@ -156,7 +173,6 @@ error do |exception|
|
|
156
173
|
raise "Something went wrong: #{exception}"
|
157
174
|
end
|
158
175
|
```
|
159
|
-
For this example I used [slack-notifier](https://github.com/stevenosloan/slack-notifier).
|
160
176
|
|
161
177
|
|
162
178
|
#### Set a default language if you are lucky enough to only maintain one language
|
@@ -191,8 +207,8 @@ ipa do
|
|
191
207
|
# Add any code you want, like incrementing the build
|
192
208
|
# number or changing the app identifier
|
193
209
|
|
194
|
-
system("ipa build") # build your project using Shenzhen
|
195
|
-
"./AppName.ipa" # Tell '
|
210
|
+
system("ipa build --verbose") # build your project using Shenzhen
|
211
|
+
"./AppName.ipa" # Tell 'deliver' where it can find the finished ipa file
|
196
212
|
end
|
197
213
|
```
|
198
214
|
|
@@ -238,36 +254,18 @@ This project is well documented, check it out on [Rubydoc](http://www.rubydoc.in
|
|
238
254
|
|
239
255
|
|
240
256
|
# Credentials
|
241
|
-
The used username (Apple ID) will be stored in the ```Deliverfile``` by default. When you run ```deliver``` for the first time on another computer, you will only be asked for the password.
|
242
|
-
|
243
|
-
Therefore it is easy to switch between projects, without needing to logout and login again.
|
244
257
|
|
245
|
-
|
246
|
-
The first time you use *Deliver* you have to enter your iTunes Connect
|
247
|
-
credentials. They will be stored in the Keychain.
|
258
|
+
A detailed description about your credentials is available on a [seperate repo](https://github.com/KrauseFx/CredentialsManager).
|
248
259
|
|
249
|
-
If you decide to remove your
|
250
|
-
credentials from the Keychain, just open the *Keychain Access*, select
|
251
|
-
*All Items* and search for 'deliver'.
|
252
260
|
|
253
|
-
|
254
|
-
You can use the following environment variables to use a specific account instead of the one stored in the keychain.
|
255
|
-
This is especially important if you have more than one iTunes Connect account in your keychain:
|
256
|
-
|
257
|
-
DELIVER_USER
|
258
|
-
DELIVER_PASSWORD
|
259
|
-
|
260
|
-
## Implement your custom solution
|
261
|
-
Take a look at [Using the exposed Ruby classes](#use-the-exposed-ruby-classes).
|
262
|
-
|
263
|
-
# Can I trust *Deliver*?
|
261
|
+
# Can I trust `deliver`?
|
264
262
|
###How does this thing even work? Is magic involved? 🎩###
|
265
263
|
|
266
|
-
|
264
|
+
`deliver` is fully open source, you can take a look at its source files. It will only modify the content you want to modify using the ```Deliverfile```. Your password will be stored in the Mac OS X keychain, but can also be passed using environment variables.
|
267
265
|
|
268
266
|
Before actually uploading anything to iTunes, ```Deliver``` will generate a [PDF summary](https://github.com/krausefx/deliver/blob/master/assets/PDFExample.png?raw=1) of the collected data.
|
269
267
|
|
270
|
-
```
|
268
|
+
```deliver``` uses the following techniques under the hood:
|
271
269
|
|
272
270
|
- The iTMSTransporter tool is used to fetch the latest app metadata from iTunes Connect and upload the updated app metadata back to Apple. It is also used to upload the ipa file. iTMSTransporter is a command line tool provided by Apple.
|
273
271
|
- With the iTMSTransporter you cannot create new version on iTunes Connect or actually publish the newly uploaded ipa file. This is why there is some browser scripting involved, using [Capybara](https://github.com/jnicklas/capybara) and [Poltergeist](https://github.com/teampoltergeist/poltergeist).
|
@@ -275,13 +273,13 @@ Before actually uploading anything to iTunes, ```Deliver``` will generate a [PDF
|
|
275
273
|
|
276
274
|
# Tips
|
277
275
|
|
278
|
-
##
|
279
|
-
Check out other tools in this collection to speed up your deployment process:
|
280
|
-
- [```snapshot```](https://github.com/KrauseFx/snapshot): Create hundreds of screenshots of your iPhone app... while doing something else.
|
281
|
-
- [```frameit```](https://github.com/KrauseFx/frameit): Want a device frame around your screenshot? Do it in an instant!
|
282
|
-
- [```PEM```](https://github.com/KrauseFx/pem): Tired of manually creating and maintaining your push certification profiles?
|
283
|
-
- [```sigh```](https://github.com/KrauseFx/sigh): Because you would rather spend your time building stuff than fighting provisioning.
|
276
|
+
## [`fastlane`](http://fastlane.tools) Toolchain
|
284
277
|
|
278
|
+
- [`fastlane`](http://fastlane.tools): Connect all deployment tools into one streamlined workflow
|
279
|
+
- [`snapshot`](https://github.com/KrauseFx/snapshot): Automate taking localized screenshots of your iOS app on every device
|
280
|
+
- [`frameit`](https://github.com/KrauseFx/frameit): Quickly put your screenshots into the right device frames
|
281
|
+
- [`PEM`](https://github.com/KrauseFx/pem): Automatically generate and renew your push notification profiles
|
282
|
+
- [`sigh`](https://github.com/KrauseFx/sigh): Because you would rather spend your time building stuff than fighting provisioning
|
285
283
|
|
286
284
|
## Available language codes
|
287
285
|
```ruby
|
@@ -293,31 +291,18 @@ You can use [SimulatorStatusMagic](https://github.com/shinydevelopment/Simulator
|
|
293
291
|
|
294
292
|
## Automatically create screenshots
|
295
293
|
|
296
|
-
|
297
|
-
|
298
|
-
**Getting started:**
|
299
|
-
|
300
|
-
- Run ```snapshot init``` in your project folder
|
301
|
-
- You can edit the new ```snapshot.js``` file with your UI Automation code
|
302
|
-
- Run ```snapshot``` to test if the screenshots work as expected
|
303
|
-
- Remove the line ```screenshots_path``` from your ```Deliverfile``` to automatically create new screenshots for each deployment.
|
304
|
-
|
305
|
-
From now on, when you start ```deliver```, it will first create the new screenshots for you, which then will be uploaded to iTunes Connect.
|
294
|
+
If you want to integrate ```deliver``` with ```snapshot```, check out [fastlane](https://github.com/KrauseFx/fastlane)!
|
306
295
|
|
307
296
|
More information about ```snapshot``` can be found on the [Snapshot GitHub page](https://github.com/KrauseFx/snapshot).
|
308
297
|
|
309
298
|
## Jenkins integration
|
310
|
-
|
311
|
-
|
312
|
-
I've been using [Jenkins App](https://github.com/stisti/jenkins-app) for a long time, where ```Deliver``` works just fine.
|
313
|
-
|
314
|
-
You should not deploy a new App Store update after every commit, since you still have to wait for your review. Instead I recommend using Git Tags, or custom triggers to deploy a new update.
|
299
|
+
Detailed instructions about how to set up `deliver` and `fastlane` in `Jenkins` can be found in the [fastlane README](https://github.com/KrauseFx/fastlane#jenkins-integration).
|
315
300
|
|
316
301
|
## Editing the ```Deliverfile```
|
317
302
|
Change syntax highlighting to *Ruby*.
|
318
303
|
|
319
304
|
# Need help?
|
320
|
-
- If there is a technical problem with ```
|
305
|
+
- If there is a technical problem with ```deliver```, submit an issue. Run ```deliver --trace``` to get the stack trace.
|
321
306
|
- I'm available for contract work - drop me an email: deliver@krausefx.com
|
322
307
|
|
323
308
|
# License
|
data/bin/deliver
CHANGED
@@ -4,25 +4,21 @@ $:.push File.expand_path("../../lib", __FILE__)
|
|
4
4
|
|
5
5
|
require 'deliver'
|
6
6
|
require 'commander/import'
|
7
|
-
require 'deliver/update_checker'
|
8
7
|
|
9
8
|
HighLine.track_eof = false
|
10
9
|
|
11
10
|
|
12
11
|
# Commander
|
13
12
|
program :version, Deliver::VERSION
|
14
|
-
program :description, 'CLI for \'Deliver\' -
|
13
|
+
program :description, 'CLI for \'Deliver\' - Upload screenshots, metadata and your app to the App Store using a single command'
|
15
14
|
program :help, 'Author', 'Felix Krause <deliver@krausefx.com>'
|
16
|
-
program :help, 'Website', 'http://
|
15
|
+
program :help, 'Website', 'http://fastlane.tools'
|
17
16
|
program :help, 'GitHub', 'https://github.com/krausefx/deliver'
|
18
17
|
program :help_formatter, :compact
|
19
18
|
|
20
19
|
global_option('--verbose') { $verbose = true }
|
21
20
|
|
22
21
|
|
23
|
-
Deliver::UpdateChecker.verify_latest_version
|
24
|
-
|
25
|
-
|
26
22
|
default_command :run
|
27
23
|
|
28
24
|
require 'deliver/commands'
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# For more information about each property, visit the GitHub documentation: https://github.com/krausefx/deliver
|
2
2
|
# Everything next to a # is a comment and will be ignored
|
3
3
|
|
4
|
-
email '[[EMAIL]]'
|
5
4
|
# hide_transporter_output # remove the '#' in the beginning of the line, to hide the output while uploading
|
6
5
|
|
7
6
|
|
@@ -16,6 +15,7 @@ apple_id "[[APPLE_ID]]"
|
|
16
15
|
|
17
16
|
# This folder has to include one folder for each language
|
18
17
|
# More information about automatic screenshot upload:
|
18
|
+
# https://github.com/KrauseFx/deliver#upload-screenshots-to-itunes-connect
|
19
19
|
screenshots_path "./deliver/screenshots/"
|
20
20
|
|
21
21
|
|
@@ -38,18 +38,22 @@ ipa do
|
|
38
38
|
# Attention: When you return a valid ipa file, this file will get uploaded and released
|
39
39
|
# If you only want to upload app metadata, remove the complete ipa block.
|
40
40
|
|
41
|
-
# system("ipa build") # build your project using Shenzhen
|
41
|
+
# system("ipa build --verbose") # build your project using Shenzhen
|
42
42
|
"./[[APP_NAME]].ipa" # Tell 'Deliver' where it can find the finished ipa file
|
43
43
|
end
|
44
44
|
|
45
|
-
# ipa "./latest.ipa" # this can be used, if you prefer manually building the ipa file
|
45
|
+
# ipa "./latest.ipa" # this can be used instead of the `do` block, if you prefer manually building the ipa file
|
46
46
|
|
47
|
-
# beta_ipa
|
47
|
+
# beta_ipa do
|
48
|
+
# system("ipa build --verbose") # customize this to build beta version
|
49
|
+
# "./ad_hoc_build.ipa" # upload ipa file using `deliver --beta`
|
50
|
+
# end
|
48
51
|
|
49
52
|
# unit_tests do
|
53
|
+
# If you use fastlane (http://github.com/krausefx/fastlane), run the tests there
|
50
54
|
# system("xctool test")
|
51
55
|
# end
|
52
56
|
|
53
57
|
success do
|
54
|
-
system("say 'Successfully deployed a new version.'")
|
58
|
+
# system("say 'Successfully deployed a new version.'")
|
55
59
|
end
|
@@ -7,7 +7,6 @@
|
|
7
7
|
#
|
8
8
|
# Everything next to a # is a comment and will be ignored
|
9
9
|
|
10
|
-
email "yourappleid@company.com"
|
11
10
|
# hide_transporter_output # remove the '#' in the beginning of the line, to hide the output while uploading
|
12
11
|
|
13
12
|
########################################
|
@@ -15,13 +14,9 @@ email "yourappleid@company.com"
|
|
15
14
|
########################################
|
16
15
|
|
17
16
|
|
18
|
-
|
19
|
-
# The app identifier is required
|
20
|
-
app_identifier "[Your App Identifier, e.g. at.felixkrause.app_name]"
|
21
|
-
|
22
|
-
|
23
17
|
# This folder has to include one folder for each language
|
24
18
|
# More information about automatic screenshot upload:
|
19
|
+
# https://github.com/KrauseFx/deliver#upload-screenshots-to-itunes-connect
|
25
20
|
screenshots_path "./screenshots"
|
26
21
|
|
27
22
|
|
@@ -51,18 +46,22 @@ ipa do
|
|
51
46
|
# Attention: When you return a valid ipa file, this file will get uploaded and released
|
52
47
|
# If you only want to upload app metadata, remove the complete ipa block.
|
53
48
|
|
54
|
-
# system("ipa build") # build your project using Shenzhen
|
49
|
+
# system("ipa build --verbose") # build your project using Shenzhen
|
55
50
|
"./[[APP_NAME]].ipa" # Tell 'Deliver' where it can find the finished ipa file
|
56
51
|
end
|
57
52
|
|
58
|
-
# ipa "./latest.ipa" # this can be used, if you prefer manually building the ipa file
|
53
|
+
# ipa "./latest.ipa" # this can be used instead of the `do` block, if you prefer manually building the ipa file
|
59
54
|
|
60
|
-
# beta_ipa
|
55
|
+
# beta_ipa do
|
56
|
+
# system("ipa build --verbose") # customize this to build beta version
|
57
|
+
# "./ad_hoc_build.ipa" # upload ipa file using `deliver --beta`
|
58
|
+
# end
|
61
59
|
|
62
60
|
# unit_tests do
|
61
|
+
# If you use fastlane (http://github.com/krausefx/fastlane), run the tests there
|
63
62
|
# system("xctool test")
|
64
63
|
# end
|
65
64
|
|
66
65
|
success do
|
67
|
-
system("say 'Successfully deployed a new version.'")
|
68
|
-
end
|
66
|
+
# system("say 'Successfully deployed a new version.'")
|
67
|
+
end
|
data/lib/deliver.rb
CHANGED
@@ -14,12 +14,14 @@ require 'deliver/deliverer'
|
|
14
14
|
require 'deliver/ipa_uploader'
|
15
15
|
require 'deliver/languages'
|
16
16
|
require 'deliver/pdf_generator'
|
17
|
-
require 'deliver/dependency_checker'
|
18
17
|
require 'deliver/deliver_process'
|
18
|
+
require 'deliver/dependency_checker'
|
19
|
+
require 'deliver/update_checker'
|
19
20
|
|
20
21
|
# Third Party code
|
21
22
|
require 'colored'
|
22
23
|
|
23
24
|
module Deliver
|
24
|
-
|
25
|
+
Deliver::UpdateChecker.verify_latest_version
|
26
|
+
Deliver::DependencyChecker.check_dependencies
|
25
27
|
end
|
data/lib/deliver/app_metadata.rb
CHANGED
@@ -5,6 +5,8 @@ module Deliver
|
|
5
5
|
end
|
6
6
|
class AppMetadataParameterError < StandardError
|
7
7
|
end
|
8
|
+
class AppMetadataTooManyScreenshotsError < StandardError
|
9
|
+
end
|
8
10
|
|
9
11
|
class AppMetadata
|
10
12
|
ITUNES_NAMESPACE = "http://apple.com/itunes/importer"
|
@@ -214,7 +216,7 @@ module Deliver
|
|
214
216
|
# Appends another screenshot to the already existing ones
|
215
217
|
# @param (String) language The language, which has to be in this list: {Deliver::Languages}.
|
216
218
|
# @param (Deliver::AppScreenshot) app_screenshot The screenshot you want to add to the app metadata.
|
217
|
-
# @raise (
|
219
|
+
# @raise (AppMetadataTooManyScreenshotsError) When there are already 5 screenshots (MAXIMUM_NUMBER_OF_SCREENSHOTS).
|
218
220
|
|
219
221
|
def add_screenshot(language, app_screenshot)
|
220
222
|
raise AppMetadataParameterError.new(INVALID_LANGUAGE_ERROR) unless Languages::ALL_LANGUAGES.include?language
|
@@ -246,7 +248,7 @@ module Deliver
|
|
246
248
|
end
|
247
249
|
|
248
250
|
if next_index > MAXIMUM_NUMBER_OF_SCREENSHOTS
|
249
|
-
raise
|
251
|
+
raise AppMetadataTooManyScreenshotsError.new("Only #{MAXIMUM_NUMBER_OF_SCREENSHOTS} screenshots are allowed per language per device type (#{app_screenshot.screen_size})")
|
250
252
|
end
|
251
253
|
|
252
254
|
# Ready for storing the screenshot into the metadata.xml now
|
@@ -312,7 +314,13 @@ module Deliver
|
|
312
314
|
self.clear_all_screenshots(language)
|
313
315
|
|
314
316
|
Dir.glob(resulting_path, File::FNM_CASEFOLD).sort.each do |path|
|
315
|
-
|
317
|
+
next if path.include?"_framed."
|
318
|
+
|
319
|
+
begin
|
320
|
+
add_screenshot(language, Deliver::AppScreenshot.new(path))
|
321
|
+
rescue AppMetadataTooManyScreenshotsError => ex
|
322
|
+
# We just use the first 5 ones
|
323
|
+
end
|
316
324
|
end
|
317
325
|
end
|
318
326
|
end
|
data/lib/deliver/commands/run.rb
CHANGED
@@ -7,16 +7,17 @@ command :run do |c|
|
|
7
7
|
c.option '--beta', 'Runs a deployment to beta build on iTunes Connect'
|
8
8
|
c.option '--skip-deploy', 'Skips deployment on iTunes Connect'
|
9
9
|
c.action do |args, options|
|
10
|
-
Deliver::
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
10
|
+
path = (Deliver::Helper.fastlane_enabled?? './fastlane' : '.')
|
11
|
+
Dir.chdir(path) do # switch the context
|
12
|
+
if File.exists?(deliver_path)
|
13
|
+
# Everything looks alright, use the given Deliverfile
|
14
|
+
options.default :beta => false, :skip_deploy => false
|
15
|
+
Deliver::Deliverer.new(deliver_path, force: options.force, is_beta_ipa: options.beta, skip_deploy: options.skip_deploy)
|
16
|
+
else
|
17
|
+
Deliver::Helper.log.warn("No Deliverfile found at path '#{deliver_path}'.")
|
18
|
+
if agree("Do you want to create a new Deliverfile at the current directory? (y/n)", true)
|
19
|
+
Deliver::DeliverfileCreator.create(enclosed_directory)
|
20
|
+
end
|
20
21
|
end
|
21
22
|
end
|
22
23
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'snapshot'
|
2
|
-
|
3
1
|
module Deliver
|
4
2
|
# This class takes care of verifying all inputs and triggering the upload process
|
5
3
|
class DeliverProcess
|
@@ -8,10 +6,6 @@ module Deliver
|
|
8
6
|
class DeliverUnitTestsError < StandardError
|
9
7
|
end
|
10
8
|
|
11
|
-
# DeliverUnitTestsError is triggered, when the unit tests of the given block failed.
|
12
|
-
class DeliverUIAutomationError < StandardError
|
13
|
-
end
|
14
|
-
|
15
9
|
# @return (Deliver::App) The App that is currently being edited.
|
16
10
|
attr_accessor :app
|
17
11
|
|
@@ -22,6 +16,9 @@ module Deliver
|
|
22
16
|
# is used to store the deploy information until the Deliverfile finished running.
|
23
17
|
attr_accessor :deploy_information
|
24
18
|
|
19
|
+
# @return (String): The app identifier of the currently used app (e.g. com.krausefx.app)
|
20
|
+
attr_accessor :app_identifier
|
21
|
+
|
25
22
|
def initialize(deploy_information = nil)
|
26
23
|
@deploy_information = deploy_information || {}
|
27
24
|
@deploy_information[:blocks] ||= {}
|
@@ -49,7 +46,7 @@ module Deliver
|
|
49
46
|
trigger_ipa_upload
|
50
47
|
|
51
48
|
call_success_block
|
52
|
-
rescue
|
49
|
+
rescue => ex
|
53
50
|
call_error_block(ex)
|
54
51
|
end
|
55
52
|
end
|
@@ -91,6 +88,8 @@ module Deliver
|
|
91
88
|
raise "Could not find an ipa file for 'beta' mode. Provide one using `beta_ipa do ... end` in your Deliverfile.".red
|
92
89
|
end
|
93
90
|
|
91
|
+
ENV["DELIVER_IPA_PATH"] = used_ipa_file
|
92
|
+
|
94
93
|
if used_ipa_file
|
95
94
|
upload_strategy = Deliver::IPA_UPLOAD_STRATEGY_APP_STORE
|
96
95
|
if is_beta_build?
|
@@ -109,7 +108,12 @@ module Deliver
|
|
109
108
|
end
|
110
109
|
end
|
111
110
|
|
111
|
+
def fetch_app_identifier_from_app_file
|
112
|
+
@app_identifier = (CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier) rescue nil)
|
113
|
+
end
|
114
|
+
|
112
115
|
def verify_ipa_file
|
116
|
+
fetch_app_identifier_from_app_file unless @app_identifier
|
113
117
|
raise Deliverfile::Deliverfile::DeliverfileDSLError.new(Deliverfile::Deliverfile::MISSING_APP_IDENTIFIER_MESSAGE.red) unless @app_identifier
|
114
118
|
raise Deliverfile::Deliverfile::DeliverfileDSLError.new(Deliverfile::Deliverfile::MISSING_VERSION_NUMBER_MESSAGE.red) unless @app_version
|
115
119
|
end
|
@@ -174,23 +178,12 @@ module Deliver
|
|
174
178
|
def set_screenshots
|
175
179
|
screens_path = @deploy_information[Deliverer::ValKey::SCREENSHOTS_PATH]
|
176
180
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
Helper.log.info("Looking for screenshots in './screenshots'.".yellow)
|
184
|
-
@app.metadata.set_all_screenshots_from_path('./screenshots')
|
185
|
-
rescue Exception => ex
|
186
|
-
# There were some UI Automation errors
|
187
|
-
raise DeliverUIAutomationError.new(ex)
|
188
|
-
end
|
189
|
-
|
190
|
-
elsif screens_path
|
191
|
-
if File.exists?('./Snapfile')
|
192
|
-
Helper.log.info("Found a Snapfile. Ignoring it. If you want 'deliver' to automatically take new screenshots for you, remove 'screenshots_path' from your 'Deliverfile'.".yellow)
|
193
|
-
end
|
181
|
+
if (ENV["DELIVER_SCREENSHOTS_PATH"] || '').length > 0
|
182
|
+
Helper.log.warn "Overwriting screenshots path from config (#{screens_path}) with (#{ENV["DELIVER_SCREENSHOTS_PATH"]})".yellow
|
183
|
+
screens_path = ENV["DELIVER_SCREENSHOTS_PATH"]
|
184
|
+
end
|
185
|
+
|
186
|
+
if screens_path
|
194
187
|
# Not using Snapfile. Not a good user.
|
195
188
|
if not @app.metadata.set_all_screenshots_from_path(screens_path)
|
196
189
|
# This path does not contain folders for each language
|
@@ -19,7 +19,7 @@ module Deliver
|
|
19
19
|
# filename itself.
|
20
20
|
def initialize(deliver_data, path = nil)
|
21
21
|
path ||= "./#{FILE_NAME}"
|
22
|
-
raise "#{FILE_NAME} not found at path '#{path}'".red unless File.exists?(path.to_s)
|
22
|
+
raise "#{FILE_NAME} not found at path '#{File.expand_path(path)}'".red unless File.exists?(path.to_s)
|
23
23
|
|
24
24
|
self.path = path
|
25
25
|
@deliver_data = deliver_data
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'credentials_manager/password_manager'
|
2
|
+
require 'credentials_manager/appfile_config'
|
3
|
+
|
1
4
|
module Deliver
|
2
5
|
# Helps new user quickly adopt Deliver
|
3
6
|
class DeliverfileCreator
|
@@ -12,14 +15,14 @@ module Deliver
|
|
12
15
|
project_name ||= Dir.pwd.split("/").last
|
13
16
|
|
14
17
|
if agree("Do you want Deliver to automatically create the Deliverfile for you based " +
|
15
|
-
"on your current app? (y/n)", true)
|
18
|
+
"on your current app? The app has to be in the App Store to use this feature. (y/n)", true)
|
16
19
|
|
17
20
|
puts "\n\nFirst, you need to login with your iTunesConnect credentials. ".yellow +
|
18
21
|
"\nThis is necessary to fetch the latest metadata from your app and use it to create a Deliverfile for you." +
|
19
22
|
"\nIf you have previously entered your credentials already, you will not be asked again."
|
20
23
|
|
21
|
-
if
|
22
|
-
identifier = ''
|
24
|
+
if CredentialsManager::PasswordManager.shared_manager.username and CredentialsManager::PasswordManager.shared_manager.password
|
25
|
+
identifier = ((CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier) rescue '') || '')
|
23
26
|
while identifier.length < 3
|
24
27
|
identifier = ask("\nApp Identifier of your app (e.g. at.felixkrause.app_name): ")
|
25
28
|
end
|
@@ -91,7 +94,7 @@ module Deliver
|
|
91
94
|
deliver.gsub!("[[APP_IDENTIFIER]]", app.app_identifier)
|
92
95
|
deliver.gsub!("[[APP_NAME]]", project_name)
|
93
96
|
deliver.gsub!("[[APPLE_ID]]", app.apple_id.to_s)
|
94
|
-
deliver.gsub!("[[EMAIL]]", PasswordManager.shared_manager.username)
|
97
|
+
deliver.gsub!("[[EMAIL]]", CredentialsManager::PasswordManager.shared_manager.username)
|
95
98
|
|
96
99
|
return deliver
|
97
100
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# Inspired by https://github.com/CocoaPods/Core/blob/master/lib/cocoapods-core/podfile/dsl.rb
|
2
|
+
require 'credentials_manager/password_manager'
|
2
3
|
|
3
4
|
module Deliver
|
4
5
|
module Deliverfile
|
@@ -102,7 +103,7 @@ module Deliver
|
|
102
103
|
# This will set the email address of the Apple ID to be used
|
103
104
|
def email(value)
|
104
105
|
value ||= yield if block_given?
|
105
|
-
PasswordManager.shared_manager(value)
|
106
|
+
CredentialsManager::PasswordManager.shared_manager(value)
|
106
107
|
end
|
107
108
|
|
108
109
|
# This will hide the output of the iTunes Connect transporter while uploading/downloading
|
data/lib/deliver/helper.rb
CHANGED
@@ -50,6 +50,11 @@ module Deliver
|
|
50
50
|
def self.transporter_path
|
51
51
|
self.xcode_path + '../Applications/Application\ Loader.app/Contents/MacOS/itms/bin/iTMSTransporter'
|
52
52
|
end
|
53
|
+
|
54
|
+
def self.fastlane_enabled?
|
55
|
+
# This is called from the root context on the first start
|
56
|
+
@@enabled ||= File.directory?"./fastlane"
|
57
|
+
end
|
53
58
|
|
54
59
|
end
|
55
60
|
end
|
data/lib/deliver/ipa_uploader.rb
CHANGED
@@ -71,15 +71,13 @@ module Deliver
|
|
71
71
|
is_okay = true
|
72
72
|
begin
|
73
73
|
transporter.upload(@app, @metadata_dir)
|
74
|
-
rescue
|
74
|
+
rescue => ex
|
75
75
|
Helper.log.debug ex
|
76
76
|
is_okay = ex.to_s.include?"ready exists a binary upload with build" # this just means, the ipa is already online
|
77
77
|
end
|
78
78
|
|
79
79
|
if is_okay
|
80
80
|
unless Helper.is_test?
|
81
|
-
`rm -rf ./#{@app.apple_id}.itmsp` # we don't need this file any more
|
82
|
-
|
83
81
|
return publish_on_itunes_connect(submit_information)
|
84
82
|
end
|
85
83
|
end
|
@@ -1,9 +1,7 @@
|
|
1
|
-
require 'deliver/password_manager'
|
2
|
-
|
3
1
|
require 'capybara'
|
4
2
|
require 'capybara/poltergeist'
|
5
|
-
require 'security'
|
6
3
|
require 'fastimage'
|
4
|
+
require 'credentials_manager/password_manager'
|
7
5
|
|
8
6
|
|
9
7
|
module Deliver
|
@@ -62,7 +60,7 @@ module Deliver
|
|
62
60
|
|
63
61
|
# Loggs in a user with the given login data on the iTC Frontend.
|
64
62
|
# You don't need to pass a username and password. It will
|
65
|
-
# Automatically be fetched using the {
|
63
|
+
# Automatically be fetched using the {CredentialsManager::PasswordManager}.
|
66
64
|
# This method will also automatically be called when triggering other
|
67
65
|
# actions like {#open_app_page}
|
68
66
|
# @param user (String) (optional) The username/email address
|
@@ -75,8 +73,8 @@ module Deliver
|
|
75
73
|
begin
|
76
74
|
Helper.log.info "Logging into iTunesConnect"
|
77
75
|
|
78
|
-
user ||= PasswordManager.shared_manager.username
|
79
|
-
password ||= PasswordManager.shared_manager.password
|
76
|
+
user ||= CredentialsManager::PasswordManager.shared_manager.username
|
77
|
+
password ||= CredentialsManager::PasswordManager.shared_manager.password
|
80
78
|
|
81
79
|
result = visit ITUNESCONNECT_URL
|
82
80
|
raise "Could not open iTunesConnect" unless result['status'] == 'success'
|
@@ -100,7 +98,7 @@ module Deliver
|
|
100
98
|
else
|
101
99
|
raise ItunesConnectLoginError.new("Looks like your login data was correct, but you do not have access to the apps.")
|
102
100
|
end
|
103
|
-
rescue
|
101
|
+
rescue => ex
|
104
102
|
Helper.log.debug(ex)
|
105
103
|
raise ItunesConnectLoginError.new("Error logging in user #{user} with the given password. Make sure you entered them correctly.")
|
106
104
|
end
|
@@ -108,7 +106,7 @@ module Deliver
|
|
108
106
|
Helper.log.info "Successfully logged into iTunesConnect"
|
109
107
|
|
110
108
|
true
|
111
|
-
rescue
|
109
|
+
rescue => ex
|
112
110
|
error_occured(ex)
|
113
111
|
end
|
114
112
|
end
|
@@ -131,11 +129,11 @@ module Deliver
|
|
131
129
|
sleep 3
|
132
130
|
|
133
131
|
if current_url.include?"wa/defaultError" # app could not be found
|
134
|
-
raise "Could not open app details for app '#{app}'. Make sure you're using the correct Apple ID and the correct Apple developer account (#{PasswordManager.shared_manager.username}).".red
|
132
|
+
raise "Could not open app details for app '#{app}'. Make sure you're using the correct Apple ID and the correct Apple developer account (#{CredentialsManager::PasswordManager.shared_manager.username}).".red
|
135
133
|
end
|
136
134
|
|
137
135
|
true
|
138
|
-
rescue
|
136
|
+
rescue => ex
|
139
137
|
error_occured(ex)
|
140
138
|
end
|
141
139
|
end
|
@@ -191,7 +189,7 @@ module Deliver
|
|
191
189
|
Helper.log.debug "Could not fetch version number of the live version for app #{app}."
|
192
190
|
return nil
|
193
191
|
end
|
194
|
-
rescue
|
192
|
+
rescue => ex
|
195
193
|
error_occured(ex)
|
196
194
|
end
|
197
195
|
end
|
@@ -242,7 +240,7 @@ module Deliver
|
|
242
240
|
if created_version != version_number
|
243
241
|
raise "Some other version ('#{created_version}') was created instead of the one you defined ('#{version_number}')"
|
244
242
|
end
|
245
|
-
rescue
|
243
|
+
rescue => ex
|
246
244
|
# Can not fetch the version number of the new version (this happens, when it's e.g. 'Developer Rejected')
|
247
245
|
unless page.has_content?version_number
|
248
246
|
raise "Some other version was created instead of the one you defined ('#{version_number}')."
|
@@ -251,7 +249,7 @@ module Deliver
|
|
251
249
|
end
|
252
250
|
|
253
251
|
true
|
254
|
-
rescue
|
252
|
+
rescue => ex
|
255
253
|
error_occured(ex)
|
256
254
|
end
|
257
255
|
end
|
@@ -275,7 +273,7 @@ module Deliver
|
|
275
273
|
# Capybara.ignore_hidden_elements = true
|
276
274
|
# first(:button, "Save").click
|
277
275
|
|
278
|
-
# rescue
|
276
|
+
# rescue => ex
|
279
277
|
# error_occured(ex)
|
280
278
|
# end
|
281
279
|
# end
|
@@ -309,7 +307,7 @@ module Deliver
|
|
309
307
|
|
310
308
|
|
311
309
|
return true
|
312
|
-
rescue
|
310
|
+
rescue => ex
|
313
311
|
error_occured(ex)
|
314
312
|
end
|
315
313
|
end
|
@@ -338,7 +336,7 @@ module Deliver
|
|
338
336
|
begin
|
339
337
|
first('a', :text => BUTTON_ADD_NEW_BUILD).click
|
340
338
|
wait_for_elements(".buildModalList")
|
341
|
-
sleep
|
339
|
+
sleep 5
|
342
340
|
rescue
|
343
341
|
if page.has_content?"Upload Date"
|
344
342
|
# That's fine, the ipa was already selected
|
@@ -360,7 +358,7 @@ module Deliver
|
|
360
358
|
raise "Could not put build itself onto production. Try opening '#{current_url}'" if error
|
361
359
|
|
362
360
|
return true
|
363
|
-
rescue
|
361
|
+
rescue => ex
|
364
362
|
error_occured(ex)
|
365
363
|
end
|
366
364
|
end
|
@@ -408,10 +406,17 @@ module Deliver
|
|
408
406
|
contains_third_party_content: false,
|
409
407
|
has_rights: false
|
410
408
|
},
|
411
|
-
advertising_identifier:
|
409
|
+
advertising_identifier: {
|
410
|
+
use_idfa: false,
|
411
|
+
serve_advertisement: false,
|
412
|
+
attribute_advertisement: false,
|
413
|
+
attribute_actions: false,
|
414
|
+
limit_ad_tracking: false
|
415
|
+
}
|
412
416
|
}
|
413
417
|
|
414
418
|
basic = "//*[@itc-radio='submitForReviewAnswers"
|
419
|
+
checkbox = "//*[@itc-checkbox='submitForReviewAnswers"
|
415
420
|
|
416
421
|
#####################
|
417
422
|
# Export Compliance #
|
@@ -450,10 +455,21 @@ module Deliver
|
|
450
455
|
# Advertising Identifier #
|
451
456
|
##########################
|
452
457
|
if page.has_content?"Advertising Identifier"
|
453
|
-
first(:xpath, "#{basic}.adIdInfo.usesIdfa.value' and @radio-value='#{perms[:advertising_identifier]}']//
|
454
|
-
|
455
|
-
if perms[:advertising_identifier]
|
456
|
-
|
458
|
+
first(:xpath, "#{basic}.adIdInfo.usesIdfa.value' and @radio-value='#{perms[:advertising_identifier][:use_idfa]}']//a").click rescue nil
|
459
|
+
|
460
|
+
if perms[:advertising_identifier][:use_idfa]
|
461
|
+
if perms[:advertising_identifier][:serve_advertisement]
|
462
|
+
first(:xpath, "#{checkbox}.adIdInfo.servesAds.value']//a").click
|
463
|
+
end
|
464
|
+
if perms[:advertising_identifier][:attribute_advertisement]
|
465
|
+
first(:xpath, "#{checkbox}.adIdInfo.tracksInstall.value']//a").click
|
466
|
+
end
|
467
|
+
if perms[:advertising_identifier][:attribute_actions]
|
468
|
+
first(:xpath, "#{checkbox}.adIdInfo.tracksAction.value']//a").click
|
469
|
+
end
|
470
|
+
if perms[:advertising_identifier][:limit_ad_tracking]
|
471
|
+
first(:xpath, "#{checkbox}.adIdInfo.limitsTracking.value']//a").click
|
472
|
+
end
|
457
473
|
end
|
458
474
|
end
|
459
475
|
|
@@ -474,7 +490,7 @@ module Deliver
|
|
474
490
|
raise "Something is missing here.".red
|
475
491
|
end
|
476
492
|
return false
|
477
|
-
rescue
|
493
|
+
rescue => ex
|
478
494
|
error_occured(ex)
|
479
495
|
end
|
480
496
|
end
|
@@ -533,4 +549,4 @@ module Deliver
|
|
533
549
|
return results
|
534
550
|
end
|
535
551
|
end
|
536
|
-
end
|
552
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'pty'
|
2
2
|
require 'shellwords'
|
3
|
-
require '
|
3
|
+
require 'credentials_manager/password_manager'
|
4
4
|
|
5
5
|
|
6
6
|
module Deliver
|
@@ -27,10 +27,10 @@ module Deliver
|
|
27
27
|
|
28
28
|
# Returns a new instance of the iTunesTransporter.
|
29
29
|
# If no username or password given, it will be taken from
|
30
|
-
# the #{
|
30
|
+
# the #{CredentialsManager::PasswordManager}
|
31
31
|
def initialize(user = nil, password = nil)
|
32
|
-
@user = (user || PasswordManager.shared_manager.username)
|
33
|
-
@password = (password || PasswordManager.shared_manager.password)
|
32
|
+
@user = (user || CredentialsManager::PasswordManager.shared_manager.username)
|
33
|
+
@password = (password || CredentialsManager::PasswordManager.shared_manager.password)
|
34
34
|
end
|
35
35
|
|
36
36
|
# Downloads the latest version of the app metadata package from iTC.
|
@@ -80,6 +80,8 @@ module Deliver
|
|
80
80
|
|
81
81
|
if result
|
82
82
|
Helper.log.info "Successfully uploaded package to iTunesConnect. It might take a few minutes until it's visible online.".green
|
83
|
+
|
84
|
+
FileUtils.rm_rf(dir) unless Helper.is_test? # we don't need the package any more, since the upload was successful
|
83
85
|
end
|
84
86
|
|
85
87
|
result
|
@@ -103,7 +105,7 @@ module Deliver
|
|
103
105
|
parse_line(line) # this is where the parsing happens
|
104
106
|
end
|
105
107
|
end
|
106
|
-
rescue
|
108
|
+
rescue => ex
|
107
109
|
Helper.log.fatal(ex.to_s)
|
108
110
|
@errors << ex.to_s
|
109
111
|
end
|
@@ -114,6 +116,7 @@ module Deliver
|
|
114
116
|
|
115
117
|
if @errors.count > 0
|
116
118
|
Helper.log.error(@errors.join("\n"))
|
119
|
+
return false
|
117
120
|
end
|
118
121
|
|
119
122
|
true
|
@@ -131,7 +134,7 @@ module Deliver
|
|
131
134
|
if $1.include?"Your Apple ID or password was entered incorrectly" or
|
132
135
|
$1.include?"This Apple ID has been locked for security reasons"
|
133
136
|
|
134
|
-
|
137
|
+
CredentialsManager::PasswordManager.shared_manager.password_seems_wrong unless Helper.is_test?
|
135
138
|
elsif $1.include?"Redundant Binary Upload. There already exists a binary upload with build"
|
136
139
|
Helper.log.fatal $1
|
137
140
|
Helper.log.fatal "You have to change the build number of your app to upload your ipa file"
|
data/lib/deliver/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deliver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Krause
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: security
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ~>
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.1.3
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ~>
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 0.1.3
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: highline
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -151,7 +137,7 @@ dependencies:
|
|
151
137
|
- !ruby/object:Gem::Version
|
152
138
|
version: '0'
|
153
139
|
- !ruby/object:Gem::Dependency
|
154
|
-
name:
|
140
|
+
name: credentials_manager
|
155
141
|
requirement: !ruby/object:Gem::Requirement
|
156
142
|
requirements:
|
157
143
|
- - '>='
|
@@ -290,12 +276,8 @@ dependencies:
|
|
290
276
|
- - '>='
|
291
277
|
- !ruby/object:Gem::Version
|
292
278
|
version: '0'
|
293
|
-
description:
|
294
|
-
|
295
|
-
\n in all languages for different screensizes to iTunesConnect and even publish
|
296
|
-
a new \n ipa file to iTunesConnect. You define your prefered deployment information
|
297
|
-
once in a so called\n Deliverfile and store it in git, to easily deploy from
|
298
|
-
every machine, even your Continuos Integration server"
|
279
|
+
description: Upload screenshots, metadata and your app to the App Store using a single
|
280
|
+
command
|
299
281
|
email:
|
300
282
|
- deliver@krausefx.com
|
301
283
|
executables:
|
@@ -330,15 +312,14 @@ files:
|
|
330
312
|
- lib/deliver/itunes_transporter.rb
|
331
313
|
- lib/deliver/languages.rb
|
332
314
|
- lib/deliver/metadata_item.rb
|
333
|
-
- lib/deliver/password_manager.rb
|
334
315
|
- lib/deliver/pdf_generator.rb
|
335
316
|
- lib/deliver/update_checker.rb
|
336
317
|
- lib/deliver/version.rb
|
337
|
-
homepage: http://
|
318
|
+
homepage: http://fastlane.tools
|
338
319
|
licenses:
|
339
320
|
- MIT
|
340
321
|
metadata: {}
|
341
|
-
post_install_message:
|
322
|
+
post_install_message: deliver requires phantomjs. Install it using 'brew update &&
|
342
323
|
brew install phantomjs'
|
343
324
|
rdoc_options: []
|
344
325
|
require_paths:
|
@@ -358,7 +339,7 @@ rubyforge_project:
|
|
358
339
|
rubygems_version: 2.2.2
|
359
340
|
signing_key:
|
360
341
|
specification_version: 4
|
361
|
-
summary:
|
362
|
-
|
342
|
+
summary: Upload screenshots, metadata and your app to the App Store using a single
|
343
|
+
command
|
363
344
|
test_files: []
|
364
345
|
has_rdoc:
|
@@ -1,110 +0,0 @@
|
|
1
|
-
require 'security'
|
2
|
-
require 'highline/import' # to hide the entered password
|
3
|
-
|
4
|
-
module Deliver
|
5
|
-
# Handles reading out the password from the keychain or asking for login data
|
6
|
-
class PasswordManager
|
7
|
-
# @return [String] The username / email address of the currently logged in user
|
8
|
-
attr_accessor :username
|
9
|
-
# @return [String] The password of the currently logged in user
|
10
|
-
attr_accessor :password
|
11
|
-
|
12
|
-
HOST = "deliver" # there might be a string appended, if user has multiple accounts
|
13
|
-
private_constant :HOST
|
14
|
-
|
15
|
-
# A singleton object, which also makes sure, to use the correct Apple ID
|
16
|
-
# @param id_to_use (String) The Apple ID email address which should be used
|
17
|
-
def self.shared_manager(id_to_use = nil)
|
18
|
-
@@instance ||= PasswordManager.new(id_to_use)
|
19
|
-
end
|
20
|
-
|
21
|
-
# A new instance of PasswordManager.
|
22
|
-
#
|
23
|
-
# This already check the Keychain if there is a username and password stored.
|
24
|
-
# If that's not the case, it will ask for login data via stdin
|
25
|
-
# @param id_to_use (String) Apple ID (e.g. steve@apple.com) which should be used for this upload.
|
26
|
-
# if given, only the password will be asked/loaded.
|
27
|
-
def initialize(id_to_use = nil)
|
28
|
-
self.username ||= ENV["DELIVER_USER"] || id_to_use || load_from_keychain[0]
|
29
|
-
self.password ||= ENV["DELIVER_PASSWORD"] || load_from_keychain[1]
|
30
|
-
|
31
|
-
if (self.username || '').length == 0 or (self.password || '').length == 0
|
32
|
-
puts "No username or password given. You can set environment variables:"
|
33
|
-
puts "DELIVER_USER, DELIVER_PASSWORD"
|
34
|
-
|
35
|
-
ask_for_login
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# This method is called, when the iTunes backend returns that the login data is wrong
|
40
|
-
# This will ask the user, if he wants to re-enter the password
|
41
|
-
def password_seems_wrong
|
42
|
-
return false if Helper.is_test?
|
43
|
-
|
44
|
-
puts "It seems like the username or password for the account '#{self.username}' is wrong."
|
45
|
-
reenter = agree("Do you want to re-enter your username and password? (y/n)", true)
|
46
|
-
if reenter
|
47
|
-
remove_from_keychain
|
48
|
-
|
49
|
-
@username = nil
|
50
|
-
@password = nil
|
51
|
-
|
52
|
-
puts "You will have to re-run the recent command to use the new username/password."
|
53
|
-
return true
|
54
|
-
else
|
55
|
-
return false
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
def ask_for_login
|
61
|
-
puts "--------------------------------------------------------------------------".green
|
62
|
-
puts "The login information you enter now will be stored in your keychain ".green
|
63
|
-
puts "More information about that on GitHub: https://github.com/krausefx/deliver".green
|
64
|
-
puts "--------------------------------------------------------------------------".green
|
65
|
-
|
66
|
-
username_was_there = self.username
|
67
|
-
|
68
|
-
while (self.username || '').length == 0
|
69
|
-
self.username = ask("Username: ")
|
70
|
-
end
|
71
|
-
|
72
|
-
self.password ||= load_from_keychain[1] # maybe there was already something stored in the keychain
|
73
|
-
|
74
|
-
if (self.password || '').length > 0
|
75
|
-
return true
|
76
|
-
else
|
77
|
-
while (self.password || '').length == 0
|
78
|
-
text = "Password: "
|
79
|
-
text = "Password (for #{self.username}): " if username_was_there
|
80
|
-
self.password = ask(text) { |q| q.echo = "*" }
|
81
|
-
end
|
82
|
-
|
83
|
-
# Now we store this information in the keychain
|
84
|
-
# Example usage taken from https://github.com/nomad/cupertino/blob/master/lib/cupertino/provisioning_portal/commands/login.rb
|
85
|
-
if Security::InternetPassword.add(hostname, self.username, self.password)
|
86
|
-
return true
|
87
|
-
else
|
88
|
-
Helper.log.error "Could not store password in keychain"
|
89
|
-
return false
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def remove_from_keychain
|
95
|
-
puts "removing keychain item: #{hostname}"
|
96
|
-
Security::InternetPassword.delete(:server => hostname)
|
97
|
-
end
|
98
|
-
|
99
|
-
def load_from_keychain
|
100
|
-
pass = Security::InternetPassword.find(:server => hostname)
|
101
|
-
|
102
|
-
return [pass.attributes['acct'], pass.password] if pass
|
103
|
-
return [nil, nil]
|
104
|
-
end
|
105
|
-
|
106
|
-
def hostname
|
107
|
-
[HOST, self.username].join('.')
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|