shenzhen 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shenzhen (0.1.0)
4
+ shenzhen (0.2.0)
5
5
  commander (~> 4.1.2)
6
6
  faraday (~> 0.8.0)
7
7
  faraday_middleware (~> 0.8.7)
data/README.md CHANGED
@@ -1,12 +1,10 @@
1
1
  # Shenzhen
2
2
  **CLI for Building & Distributing iOS Apps (.ipa Files)**
3
3
 
4
- Create `.ipa` files and then distribute them with [TestFlight](https://testflightapp.com/), all from the command line!
4
+ Create `.ipa` files and then distribute them with [TestFlight](https://testflightapp.com/) or [HockeyApp](http://www.hockeyapp.net), all from the command line!
5
5
 
6
6
  Less cumbersome than clicking around in Xcode, and less hassle than rolling your own build script--Shenzhen radically improves the process of getting new builds out to testers and enterprises.
7
7
 
8
- This project is starting with TestFlight, but will move to support other popular distribution methods, such as S3, CloudApp, and / or Dropbox. Suggestions (and pull requests) are very welcome.
9
-
10
8
  > `shenzhen` is named for [深圳](http://en.wikipedia.org/wiki/Shenzhen), the Chinese city famous for its role as the center of manufacturing for a majority of consumer electronics, including iPhones and iPads. Its [sister project](https://github.com/mattt/cupertino)'s namesake, [Cupertino, CA](http://en.wikipedia.org/wiki/Cupertino,_California), is home to Apple, Inc.'s world headquarters.
11
9
 
12
10
  ## Installation
@@ -26,7 +24,8 @@ $ ipa
26
24
 
27
25
  Commands:
28
26
  build Create a new .ipa file for your app
29
- distribute:testflight Distribute an .ipa file over testflight
27
+ distribute:testflight Distribute an .ipa file over TestFlight
28
+ distribute:hockeyapp Distribute an .ipa file over HockeyApp
30
29
  help Display global or [command] help documentation.
31
30
 
32
31
  Aliases:
@@ -1,5 +1,5 @@
1
1
  module Shenzhen
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
4
4
 
5
5
  require 'shenzhen/agvtool'
@@ -1,6 +1,7 @@
1
1
  $:.push File.expand_path('../', __FILE__)
2
2
 
3
3
  require 'plugins/testflight'
4
+ require 'plugins/hockeyapp'
4
5
 
5
6
  require 'commands/build'
6
7
  require 'commands/distribute'
@@ -48,13 +48,13 @@ command :build do |c|
48
48
  ENV['CC'] = nil # Fix for RVM
49
49
  abort unless system %{xcodebuild #{flags.join(' ')} clean build 1> /dev/null}
50
50
 
51
- log "xcrun", "PackageApplication"
52
-
53
51
  @xcodebuild_settings = Shenzhen::XcodeBuild.settings(flags)
54
52
  @app_path = File.join(@xcodebuild_settings['BUILT_PRODUCTS_DIR'], @xcodebuild_settings['PRODUCT_NAME']) + ".app"
55
53
  @dsym_path = @app_path + ".dSYM"
56
54
  @dsym_filename = "#{@xcodebuild_settings['PRODUCT_NAME']}.app.dSYM"
57
55
  @ipa_path = File.join(Dir.pwd, @xcodebuild_settings['PRODUCT_NAME']) + ".ipa"
56
+
57
+ log "xcrun", "PackageApplication"
58
58
  abort unless system %{xcrun -sdk iphoneos PackageApplication -v "#{@app_path}" -o "#{@ipa_path}" --embed "#{@dsym_path}" 1> /dev/null}
59
59
 
60
60
  log "zip", @dsym_filename
@@ -0,0 +1,126 @@
1
+ require 'openssl'
2
+ require 'faraday'
3
+ require 'faraday_middleware'
4
+
5
+ module Shenzhen::Plugins
6
+ module HockeyApp
7
+ class Client
8
+ HOSTNAME = 'rink.hockeyapp.net'
9
+
10
+ def initialize(api_token)
11
+ @api_token = api_token
12
+ @connection = Faraday.new(:url => "https://#{HOSTNAME}") do |builder|
13
+ builder.request :multipart
14
+ builder.request :url_encoded
15
+ builder.response :json, :content_type => /\bjson$/
16
+ builder.use FaradayMiddleware::FollowRedirects
17
+ builder.adapter :net_http
18
+ end
19
+ end
20
+
21
+ def upload_build(ipa, options)
22
+ options[:ipa] = Faraday::UploadIO.new(ipa, 'application/octet-stream')
23
+
24
+ if dsym_filename = options.delete(:dsym_filename)
25
+ options[:dsym] = Faraday::UploadIO.new(dsym_filename, 'application/octet-stream')
26
+ end
27
+
28
+ @connection.post do |req|
29
+ if options[:public_identifer].nil?
30
+ req.url("/api/2/apps/upload")
31
+ else
32
+ req.url("/api/2/apps/#{options.delete(:public_identifer)}/app_versions")
33
+ end
34
+ req.headers['X-HockeyAppToken'] = @api_token
35
+ req.body = options
36
+ end.on_complete do |env|
37
+ yield env[:status], env[:body] if block_given?
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ command :'distribute:hockeyapp' do |c|
45
+ c.syntax = "ipa distribute:hockeyapp [options]"
46
+ c.summary = "Distribute an .ipa file over HockeyApp"
47
+ c.description = ""
48
+ c.option '-f', '--file FILE', ".ipa file for the build"
49
+ c.option '-d', '--dsym FILE', "zipped .dsym package for the build"
50
+ c.option '-t', '--token TOKEN', "API Token. Available at https://rink.hockeyapp.net/manage/auth_tokens"
51
+ c.option '-i', '--identifier PUBLIC_IDENTIFIER', "Public identifier of the app you are targeting, if not specified HockeyApp will use the bundle identifier to choose the right"
52
+ c.option '-m', '--notes NOTES', "Release notes for the build (Default: Textile)"
53
+ c.option '--markdown', 'Notes are written with Markdown'
54
+ c.option '--tags TAGS', "Comma separated list of tags which will receive access to the build"
55
+ c.option '--notify', "Notify permitted teammates to install the build"
56
+ c.option '--downloadOff', "Upload but don't allow download of this version just yet"
57
+
58
+ c.option '-q', '--quiet', "Silence warning and success messages"
59
+
60
+
61
+ c.action do |args, options|
62
+ determine_file! unless @file = options.file
63
+ say_error "Missing or unspecified .ipa file" and abort unless @file and File.exist?(@file)
64
+
65
+ determine_dsym! unless @dsym = options.dsym
66
+ say_error "Specified dSYM.zip file doesn't exist" if @dsym and !File.exist?(@dsym)
67
+
68
+ determine_api_token! unless @api_token = options.token
69
+ say_error "Missing API Token" and abort unless @api_token
70
+
71
+ determine_notes! unless @notes = options.notes
72
+ say_error "Missing release notes" and abort unless @notes
73
+
74
+ parameters = {}
75
+ parameters[:public_identifer] = options.identifier if options.identifier
76
+ parameters[:notes] = @notes
77
+ parameters[:notes_type] = options.markdown ? "1" : "0"
78
+ parameters[:notify] = "1" if options.notify && !options.downloadOff
79
+ parameters[:status] = options.downloadOff ? "1" : "2"
80
+ parameters[:tags] = options.tags if options.tags
81
+ parameters[:dsym_filename] = @dsym if @dsym
82
+
83
+
84
+ client = Shenzhen::Plugins::HockeyApp::Client.new(@api_token)
85
+ response = client.upload_build(@file, parameters)
86
+ case response.status
87
+ when 200...300
88
+ say_ok "Build successfully uploaded to HockeyApp"
89
+ else
90
+ say_error "Error uploading to HockeyApp: #{response.body}"
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def determine_api_token!
97
+ @api_token ||= ask "API Token:"
98
+ end
99
+
100
+ def determine_file!
101
+ files = Dir['*.ipa']
102
+ @file ||= case files.length
103
+ when 0 then nil
104
+ when 1 then files.first
105
+ else
106
+ @file = choose "Select an .ipa File:", *files
107
+ end
108
+ end
109
+
110
+ def determine_dsym!
111
+ dsym_files = Dir['*.dSYM.zip']
112
+ @dsym ||= case dsym_files.length
113
+ when 0 then nil
114
+ when 1 then dsym_files.first
115
+ else
116
+ @dsym = choose "Select a .dSYM.zip file:", *dsym_files
117
+ end
118
+ end
119
+
120
+ def determine_notes!
121
+ placeholder = %{What's new in this release: }
122
+
123
+ @notes = ask_editor placeholder
124
+ @notes = nil if @notes == placeholder
125
+ end
126
+ end
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shenzhen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-09 00:00:00.000000000Z
12
+ date: 2012-10-12 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70357169989920 !ruby/object:Gem::Requirement
16
+ requirement: &70170608319000 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.6.1
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70357169989920
24
+ version_requirements: *70170608319000
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &70357169987940 !ruby/object:Gem::Requirement
27
+ requirement: &70170608318420 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.9.2
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70357169987940
35
+ version_requirements: *70170608318420
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: commander
38
- requirement: &70357169985980 !ruby/object:Gem::Requirement
38
+ requirement: &70170608317720 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 4.1.2
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70357169985980
46
+ version_requirements: *70170608317720
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: json
49
- requirement: &70357169976100 !ruby/object:Gem::Requirement
49
+ requirement: &70170608317140 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.7.3
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70357169976100
57
+ version_requirements: *70170608317140
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: faraday
60
- requirement: &70357169973340 !ruby/object:Gem::Requirement
60
+ requirement: &70170608316680 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.8.0
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70357169973340
68
+ version_requirements: *70170608316680
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: faraday_middleware
71
- requirement: &70357169971200 !ruby/object:Gem::Requirement
71
+ requirement: &70170608316200 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: 0.8.7
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *70357169971200
79
+ version_requirements: *70170608316200
80
80
  description: CLI for Building & Distributing iOS Apps (.ipa Files)
81
81
  email: m@mattt.me
82
82
  executables:
@@ -90,12 +90,14 @@ files:
90
90
  - ./lib/shenzhen/commands/build.rb
91
91
  - ./lib/shenzhen/commands/distribute.rb
92
92
  - ./lib/shenzhen/commands.rb
93
+ - ./lib/shenzhen/plugins/hockeyapp.rb
93
94
  - ./lib/shenzhen/plugins/testflight.rb
94
95
  - ./lib/shenzhen/xcodebuild.rb
95
96
  - ./lib/shenzhen.rb
96
97
  - ./LICENSE
97
98
  - ./Rakefile
98
99
  - ./README.md
100
+ - ./shenzhen-0.1.0.gem
99
101
  - ./shenzhen.gemspec
100
102
  - bin/ipa
101
103
  homepage: http://github.com/mattt/shenzhen
@@ -112,7 +114,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
112
114
  version: '0'
113
115
  segments:
114
116
  - 0
115
- hash: -2320972868632584491
117
+ hash: 4537962558176197982
116
118
  required_rubygems_version: !ruby/object:Gem::Requirement
117
119
  none: false
118
120
  requirements:
@@ -121,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
123
  version: '0'
122
124
  segments:
123
125
  - 0
124
- hash: -2320972868632584491
126
+ hash: 4537962558176197982
125
127
  requirements: []
126
128
  rubyforge_project:
127
129
  rubygems_version: 1.8.15