deliver 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 09ef987a38d4e23c32084e479906c80647c13e0f
4
- data.tar.gz: 91bbad8fbe088f74439a3c6a3691838f9f340930
3
+ metadata.gz: be16fd06999f4fd2f5621ea5b1c4997f461776f6
4
+ data.tar.gz: d694a822e357510159c6c54cb9fe85259294df81
5
5
  SHA512:
6
- metadata.gz: 5085795e4ce3188b7919a869b739c90752a4ec11939775b94f5eb7b5d7cd3cd7579d7d106754cb80569cd01da13c2254854cf632291b812806da04417149c1d1
7
- data.tar.gz: f2233fb71a3d6b017efd4a971fe8d2ec963cd99a68ad5efdf7f94fbe2f57ffb4e3bf862a34abb2c70d4461d453059e6e1c6a0b1cfcf5aac42b406152edf05a09
6
+ metadata.gz: 4b1cbc989b40241a3f86ee2d1a85e670725b573f4cd3834be0efe92f799458e879b5521258aae7656c35074d5a18a760496b0a75134534f31ced29fd4f171e9a
7
+ data.tar.gz: 65a221d7ce61b6e083b0a3f07caef042e62a17def9d02b37f862c189f5d4b0020d6a8fdb81cf136e220b50230ccae355983779c5e3013d52782ca7c55bcdda39
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- deliver (0.1.0)
4
+ deliver (0.1.1)
5
5
  capybara (~> 2.4.3)
6
6
  colored
7
7
  commander (~> 4.2.0)
data/README.md CHANGED
@@ -14,7 +14,7 @@ Deliver - Continuous Deployment for iOS
14
14
  Updating your iOS app should not be painful and time consuming. Automate the
15
15
  whole process to start with Continuous Deployment.
16
16
 
17
- ```Deliver``` **can upload ipa files, app screenshots and more to the iTunesConnect backend**, which means, you can deploy new iPhone app updates just by using one command.
17
+ ```Deliver``` **can upload ipa files, app screenshots and more to the iTunes Connect backend**, which means, you can deploy new iPhone app updates just by using one command.
18
18
 
19
19
  Follow the developer on Twitter: [@KrauseFx](https://twitter.com/KrauseFx)
20
20
 
@@ -34,11 +34,11 @@ Follow the developer on Twitter: [@KrauseFx](https://twitter.com/KrauseFx)
34
34
 
35
35
  # Features
36
36
  - Upload hundreds of screenshots with different languages from different devices
37
- - Upload a new ipa file to iTunesConnect without Xcode from any computer
37
+ - Upload a new ipa file to iTunes Connect without Xcode from any computer
38
38
  - Update app metadata
39
39
  - Easily implement a real Continuous Deployment process
40
40
  - Store the configuration in git to easily deploy from **any** computer, including your Continuous Integration server (e.g. Jenkins)
41
- - 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) (Yes, those are screenshots on taken for all screen sizes)
41
+ - 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) (Yes, those are screenshots taken for all screen sizes)
42
42
 
43
43
  # Installation
44
44
 
@@ -50,7 +50,7 @@ Make sure, you have the latest version of the Xcode command line tools installed
50
50
 
51
51
  xcode-select --install
52
52
 
53
- Install phantomjs (this is needed to control the iTunesConnect frontend)
53
+ Install phantomjs (this is needed to control the iTunes Connect frontend)
54
54
 
55
55
  brew update && brew install phantomjs
56
56
 
@@ -59,12 +59,12 @@ If you don't have homebrew installed already, [install it here](http://brew.sh/)
59
59
  # Quick Start
60
60
 
61
61
 
62
- The guide will create all the necessary files for you, using the existing app metadata from iTunesConnect.
62
+ The guide will create all the necessary files for you, using the existing app metadata from iTunes Connect.
63
63
 
64
64
  - ```cd [your_project_folder]```
65
65
  - ```deliver init```
66
- - When your app is already in the AppStore: ```y```
67
- - Enter your iTunesConnect credentials
66
+ - When your app is already in the App Store: ```y```
67
+ - Enter your iTunes Connect credentials
68
68
  - Enter your app identifier
69
69
  - Enjoy a good drink, while the computer does all the work for you
70
70
  - When it's a new app: ```n```
@@ -85,12 +85,12 @@ Why should you have to remember complicated commands and parameters?
85
85
 
86
86
  Store your configuration in a text file to easily deploy from any computer.
87
87
 
88
- Run ```deliver init``` to create a new ```Deliverfile```. You can either let the wizard generate a file based on the metadata from iTunesConnect or create one from a template.
88
+ Run ```deliver init``` to create a new ```Deliverfile```. You can either let the wizard generate a file based on the metadata from iTunes Connect or create one from a template.
89
89
 
90
90
  Once you created your configuration, just run ```deliver```.
91
91
 
92
92
  Here are a few example files:
93
- #### Upload screenshots to iTunesConnect
93
+ #### Upload screenshots to iTunes Connect
94
94
  ```ruby
95
95
  app_identifier "net.sunapps.1"
96
96
  version "1.1"
@@ -99,7 +99,7 @@ screenshots_path "./screenshots"
99
99
  ```
100
100
  The screenshots folder must include one subfolder per language (see [Available language codes](#available-language-codes))
101
101
 
102
- #### Upload a new ipa file with a changelog to the AppStore
102
+ #### Upload a new ipa file with a changelog to the App Store
103
103
  This will submit a new update to Apple
104
104
  ```ruby
105
105
  ipa "./latest.ipa"
@@ -202,17 +202,21 @@ This project is well documented, check it out on [Rubydoc](http://www.rubydoc.in
202
202
 
203
203
 
204
204
  # Credentials
205
+ 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.
206
+
207
+ Therefore it is easy to switch between projects, without needing to logout and login again.
205
208
 
206
209
  ## Use the Keychain
207
- The first time you use *Deliver* you have to enter your iTunesConnect
210
+ The first time you use *Deliver* you have to enter your iTunes Connect
208
211
  credentials. They will be stored in the Keychain.
209
212
 
210
213
  If you decide to remove your
211
214
  credentials from the Keychain, just open the *Keychain Access*, select
212
- *All Items* and search for 'itunesconnect.apple.com'.
215
+ *All Items* and search for 'deliver'.
213
216
 
214
217
  ## Use environment variables
215
- You can use the following environment variables to use a specific account instead of the one stored in the keychain:
218
+ You can use the following environment variables to use a specific account instead of the one stored in the keychain.
219
+ This is especially important if you have more than one iTunes Connect account in your keychain:
216
220
 
217
221
  DELIVER_USER
218
222
  DELIVER_PASSWORD
@@ -229,8 +233,8 @@ Before actually uploading anything to iTunes, ```Deliver``` will generate a [PDF
229
233
 
230
234
  ```Deliver``` uses the following techniques under the hood:
231
235
 
232
- - The iTMSTransporter tool is used to fetch the latest app metadata from iTunesConnect 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.
233
- - With the iTMSTransporter you cannot create new version on iTunesConnect 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).
236
+ - 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.
237
+ - 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).
234
238
  - The iTunes search API to find missing information about a certain app, like the *apple_id* when you only pass the *bundle_identifier*.
235
239
 
236
240
  # Tips
@@ -263,7 +267,7 @@ These are features, which are implemented, but not yet fully tested and producti
263
267
  ```ruby
264
268
  beta_ipa "./latest.ipa"
265
269
  ```
266
- This will upload the ipa file to iTunesConnect and mark the uploaded build as Beta build.
270
+ This will upload the ipa file to iTunes Connect and mark the uploaded build as Beta build.
267
271
 
268
272
  # Need help?
269
273
  - If there is a technical problem with ```Deliver```, submit an issue. Run ```deliver --trace``` to get the stacktrace.
@@ -1,7 +1,7 @@
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
-
4
+ email '[[EMAIL]]'
5
5
 
6
6
  ########################################
7
7
  # App Metadata
@@ -9,6 +9,7 @@
9
9
 
10
10
  # The app identifier is required
11
11
  app_identifier "[[APP_IDENTIFIER]]"
12
+ apple_id "[[APPLE_ID]]"
12
13
 
13
14
 
14
15
  # This folder has to include one folder for each language
@@ -7,7 +7,7 @@
7
7
  #
8
8
  # Everything next to a # is a comment and will be ignored
9
9
 
10
-
10
+ email "yourappleid@company.com"
11
11
 
12
12
  ########################################
13
13
  # App Metadata
data/lib/deliver/app.rb CHANGED
@@ -43,8 +43,15 @@ module Deliver
43
43
  begin
44
44
  self.apple_id = Deliver::ItunesSearchApi.fetch_by_identifier(app_identifier)['trackId']
45
45
  rescue
46
- Helper.log.fatal "Could not find Apple ID based on the app identifier '#{app_identifier}'. Maybe the app is not in the AppStore yet?"
47
- raise "Please pass a valid Apple ID using 'apple_id'".red
46
+ unless Helper.is_test?
47
+ Helper.log.info "Could not find Apple ID based on the app identifier in the US App Store. Maybe the app is not yet in the store?".yellow
48
+
49
+ while ((self.apple_id || '').to_s.length == 0) || ((self.apple_id || 0).to_i == 0)
50
+ self.apple_id = ask("\nApple ID of your app (e.g. 284882215): ")
51
+ end
52
+ else
53
+ raise "Please pass a valid Apple ID using 'apple_id'".red
54
+ end
48
55
  end
49
56
  end
50
57
  end
@@ -18,7 +18,7 @@ module Deliver
18
18
  "\nThis is necessary to fetch the latest metadata from your app and use it to create a Deliverfile for you." +
19
19
  "\nIf you have previously entered your credentials already, you will not be asked again."
20
20
 
21
- if Deliver::PasswordManager.new.username and Deliver::PasswordManager.new.password
21
+ if Deliver::PasswordManager.shared_manager.username and Deliver::PasswordManager.shared_manager.password
22
22
  identifier = ''
23
23
  while identifier.length < 3
24
24
  identifier = ask("\nApp Identifier of your app (e.g. at.felixkrause.app_name): ")
@@ -86,6 +86,8 @@ module Deliver
86
86
  deliver = File.read("#{gem_path}/lib/assets/DeliverfileDefault")
87
87
  deliver.gsub!("[[APP_IDENTIFIER]]", app.app_identifier)
88
88
  deliver.gsub!("[[APP_NAME]]", project_name)
89
+ deliver.gsub!("[[APPLE_ID]]", app.apple_id.to_s)
90
+ deliver.gsub!("[[EMAIL]]", PasswordManager.shared_manager.username)
89
91
 
90
92
  return deliver
91
93
  end
@@ -101,6 +101,12 @@ module Deliver
101
101
  @deliver_data.set_new_value(Deliverer::ValKey::BETA_IPA, value)
102
102
  end
103
103
 
104
+ # This will set the email address of the Apple ID to be used
105
+ def email(value)
106
+ value ||= yield if block_given?
107
+ PasswordManager.shared_manager(value)
108
+ end
109
+
104
110
  # Set the apps new version number.
105
111
  #
106
112
  # If you do not set this, it will automatically being fetched from the
@@ -72,8 +72,8 @@ module Deliver
72
72
  begin
73
73
  Helper.log.info "Logging into iTunesConnect"
74
74
 
75
- user ||= PasswordManager.new.username
76
- password ||= PasswordManager.new.password
75
+ user ||= PasswordManager.shared_manager.username
76
+ password ||= PasswordManager.shared_manager.password
77
77
 
78
78
  result = visit ITUNESCONNECT_URL
79
79
  raise "Could not open iTunesConnect" unless result['status'] == 'success'
@@ -119,7 +119,7 @@ module Deliver
119
119
  sleep 3
120
120
 
121
121
  if current_url.include?"wa/defaultError" # app could not be found
122
- 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.new.username}).".red
122
+ 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
123
123
  end
124
124
 
125
125
  true
@@ -23,8 +23,8 @@ module Deliver
23
23
  # If no username or password given, it will be taken from
24
24
  # the #{Deliver::PasswordManager}
25
25
  def initialize(user = nil, password = nil)
26
- @user = (user || PasswordManager.new.username)
27
- @password = (password || PasswordManager.new.password)
26
+ @user = (user || PasswordManager.shared_manager.username)
27
+ @password = (password || PasswordManager.shared_manager.password)
28
28
  end
29
29
 
30
30
  # Downloads the latest version of the app metadata package from iTC.
@@ -112,7 +112,7 @@ module Deliver
112
112
  if $1.include?"Your Apple ID or password was entered incorrectly" or
113
113
  $1.include?"This Apple ID has been locked for security reasons"
114
114
 
115
- Deliver::PasswordManager.new.password_seems_wrong
115
+ Deliver::PasswordManager.shared_manager.password_seems_wrong
116
116
  end
117
117
 
118
118
  elsif line =~ WARNING_REGEX
@@ -9,15 +9,23 @@ module Deliver
9
9
  # @return [String] The password of the currently logged in user
10
10
  attr_accessor :password
11
11
 
12
- HOST = "itunesconnect.apple.com"
12
+ HOST = "deliver" # there might be a string appended, if user has multiple accounts
13
13
  private_constant :HOST
14
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
+
15
21
  # A new instance of PasswordManager.
16
22
  #
17
23
  # This already check the Keychain if there is a username and password stored.
18
24
  # If that's not the case, it will ask for login data via stdin
19
- def initialize
20
- self.username ||= ENV["DELIVER_USER"] || load_from_keychain[0]
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]
21
29
  self.password ||= ENV["DELIVER_PASSWORD"] || load_from_keychain[1]
22
30
 
23
31
  if (self.username || '').length == 0 or (self.password || '').length == 0
@@ -36,9 +44,10 @@ module Deliver
36
44
  puts "It seems like the username or password for the account '#{self.username}' is wrong."
37
45
  reenter = agree("Do you want to re-enter your username and password? (y/n)", true)
38
46
  if reenter
47
+ remove_from_keychain
48
+
39
49
  @username = nil
40
50
  @password = nil
41
- remove_from_keychain
42
51
 
43
52
  puts "You will have to re-run the recent command to use the new username/password."
44
53
  return true
@@ -54,33 +63,48 @@ module Deliver
54
63
  puts "More information about that on GitHub: https://github.com/krausefx/deliver".green
55
64
  puts "--------------------------------------------------------------------------".green
56
65
 
66
+ username_was_there = self.username
67
+
57
68
  while (self.username || '').length == 0
58
69
  self.username = ask("Username: ")
59
70
  end
60
71
 
61
- while (self.password || '').length == 0
62
- self.password = ask("Password: ") { |q| q.echo = "*" }
63
- end
72
+ self.password ||= load_from_keychain[1] # maybe there was already something stored in the keychain
64
73
 
65
- # Now we store this information in the keychain
66
- # Example usage taken from https://github.com/nomad/cupertino/blob/master/lib/cupertino/provisioning_portal/commands/login.rb
67
- if Security::InternetPassword.add(HOST, self.username, self.password)
74
+ if (self.password || '').length > 0
68
75
  return true
69
76
  else
70
- Helper.log.error "Could not store password in keychain"
71
- return false
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
72
91
  end
73
92
  end
74
93
 
75
94
  def remove_from_keychain
76
- Security::InternetPassword.delete(:server => HOST)
95
+ puts "removing keychain item: #{hostname}"
96
+ Security::InternetPassword.delete(:server => hostname)
77
97
  end
78
98
 
79
99
  def load_from_keychain
80
- pass = Security::InternetPassword.find(:server => HOST)
100
+ pass = Security::InternetPassword.find(:server => hostname)
81
101
 
82
102
  return [pass.attributes['acct'], pass.password] if pass
83
103
  return [nil, nil]
84
104
  end
105
+
106
+ def hostname
107
+ [HOST, self.username].join('.')
108
+ end
85
109
  end
86
110
  end
@@ -1,3 +1,3 @@
1
1
  module Deliver
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -32,7 +32,6 @@ describe Deliver do
32
32
  FileUtils.rm_rf("/tmp/#{apple_id}.itmsp") rescue nil
33
33
 
34
34
 
35
-
36
35
 
37
36
  Deliver::ItunesTransporter.set_mock_file("spec/responses/transporter/download_valid_apple_id.txt")
38
37
 
@@ -60,6 +59,8 @@ describe Deliver do
60
59
  correct = File.read("./lib/assets/DeliverfileDefault")
61
60
  correct.gsub!("[[APP_IDENTIFIER]]", 'net.sunapps.54')
62
61
  correct.gsub!("[[APP_NAME]]", project_name)
62
+ correct.gsub!("[[EMAIL]]", ENV["DELIVER_USER"])
63
+ correct.gsub!("[[APPLE_ID]]", apple_id.to_s)
63
64
  expect(File.read("/tmp/Deliverfile")).to eq(correct)
64
65
 
65
66
  expect(File.directory?([deliver_path, "screenshots"].join("/"))).to eq(true)
data/spec/spec_helper.rb CHANGED
@@ -10,6 +10,9 @@ require 'mocking/webmocking'
10
10
  require 'mocking/transporter_mocking'
11
11
 
12
12
 
13
+ ENV["DELIVER_USER"] = "DELIVERUSER"
14
+ ENV["DELIVER_PASSWORD"] = "DELIVERPASS"
15
+
13
16
  # This module is only used to check the environment is currently a testing env
14
17
  module SpecHelper
15
18
 
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.1.1
4
+ version: 0.2.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: 2014-11-05 00:00:00.000000000 Z
11
+ date: 2014-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: security