shenzhen 0.4.0 → 0.5.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +16 -5
- data/README.md +13 -2
- data/Rakefile +1 -2
- data/lib/shenzhen.rb +1 -1
- data/lib/shenzhen/commands.rb +1 -0
- data/lib/shenzhen/commands/build.rb +24 -6
- data/lib/shenzhen/plugins/ftp.rb +48 -22
- data/lib/shenzhen/plugins/hockeyapp.rb +5 -4
- data/lib/shenzhen/plugins/s3.rb +133 -0
- data/lib/shenzhen/plugins/testflight.rb +1 -0
- data/nada.ipa +0 -0
- data/shenzhen.gemspec +3 -0
- metadata +38 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fb28a156e7d7ae587fd7111136ad03abcadbb2b0
|
|
4
|
+
data.tar.gz: 36b8b8fd8718548b6e2cc815fc7724297f4a639d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5c18315a884e2e44e4c0630fcbdda1b23d8a31e762b26380766e48d4a47319f39d5f775d233ee5499170238bd3b86b4981b8b5f4caca90bb1fd98a022cece0f2
|
|
7
|
+
data.tar.gz: ef91e63e346f9b012a8d236e1a0cc9a17a90c04203094d7ddeedb731074b0f5500dfac8ab727210eb3880dbeddacc86ea30c2102fad47aa17a114114bab2d600
|
data/Gemfile.lock
CHANGED
|
@@ -1,28 +1,39 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
shenzhen (0.
|
|
4
|
+
shenzhen (0.5.0)
|
|
5
|
+
aws-sdk (~> 1.0)
|
|
5
6
|
commander (~> 4.1)
|
|
6
7
|
dotenv (~> 0.7)
|
|
7
8
|
faraday (~> 0.8)
|
|
8
9
|
faraday_middleware (~> 0.9)
|
|
9
10
|
json (~> 1.8)
|
|
11
|
+
net-sftp (~> 2.1.2)
|
|
10
12
|
|
|
11
13
|
GEM
|
|
12
14
|
remote: https://rubygems.org/
|
|
13
15
|
specs:
|
|
14
|
-
|
|
16
|
+
aws-sdk (1.20.0)
|
|
17
|
+
json (~> 1.4)
|
|
18
|
+
nokogiri (>= 1.4.4, < 1.6.0)
|
|
19
|
+
uuidtools (~> 2.1)
|
|
20
|
+
commander (4.1.5)
|
|
15
21
|
highline (~> 1.6.11)
|
|
16
|
-
dotenv (0.
|
|
17
|
-
faraday (0.8.
|
|
18
|
-
multipart-post (~> 1.
|
|
22
|
+
dotenv (0.9.0)
|
|
23
|
+
faraday (0.8.8)
|
|
24
|
+
multipart-post (~> 1.2.0)
|
|
19
25
|
faraday_middleware (0.9.0)
|
|
20
26
|
faraday (>= 0.7.4, < 0.9)
|
|
21
27
|
highline (1.6.19)
|
|
22
28
|
json (1.8.0)
|
|
23
29
|
multipart-post (1.2.0)
|
|
30
|
+
net-sftp (2.1.2)
|
|
31
|
+
net-ssh (>= 2.6.5)
|
|
32
|
+
net-ssh (2.7.0)
|
|
33
|
+
nokogiri (1.5.10)
|
|
24
34
|
rake (0.9.6)
|
|
25
35
|
rspec (0.6.4)
|
|
36
|
+
uuidtools (2.1.4)
|
|
26
37
|
|
|
27
38
|
PLATFORMS
|
|
28
39
|
ruby
|
data/README.md
CHANGED
|
@@ -24,6 +24,7 @@ Shenzhen adds the `ipa` command to your PATH:
|
|
|
24
24
|
distribute:testflight Distribute an .ipa file over TestFlight
|
|
25
25
|
distribute:hockeyapp Distribute an .ipa file over HockeyApp
|
|
26
26
|
distribute:ftp Distribute an .ipa file over FTP
|
|
27
|
+
distribute:S3 Distribute an .ipa file over Amazon S3
|
|
27
28
|
help Display global or [command] help documentation.
|
|
28
29
|
|
|
29
30
|
Aliases:
|
|
@@ -50,11 +51,21 @@ Shenzhen adds the `ipa` command to your PATH:
|
|
|
50
51
|
|
|
51
52
|
$ ipa distribute:hockeyapp -t API_TOKEN
|
|
52
53
|
|
|
53
|
-
> Shenzhen will load credentials from the environment
|
|
54
|
+
> Shenzhen will load credentials from the environment variable `HOCKEYAPP_API_TOKEN` unless otherwise specified.
|
|
54
55
|
|
|
55
56
|
#### FTP Distribution
|
|
56
57
|
|
|
57
|
-
$ ipa distribute:
|
|
58
|
+
$ ipa distribute:ftp --host HOST -u USER -p PASSWORD -P FTP_PATH
|
|
59
|
+
|
|
60
|
+
#### SFTP Distribution
|
|
61
|
+
|
|
62
|
+
$ ipa distribute:sftp --host HOST -u USER -p PASSWORD -P FTP_PATH
|
|
63
|
+
|
|
64
|
+
#### Amazon S3 Distribution
|
|
65
|
+
|
|
66
|
+
$ ipa distribute:s3 -a ACCESS_KEY_ID -s SECRET_ACCESS_KEY -b BUCKET
|
|
67
|
+
|
|
68
|
+
> Shenzhen will load credentials from the environment variable `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` and `AWS_REGION` unless otherwise specified.
|
|
58
69
|
|
|
59
70
|
## Contact
|
|
60
71
|
|
data/Rakefile
CHANGED
data/lib/shenzhen.rb
CHANGED
data/lib/shenzhen/commands.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
|
|
1
3
|
command :build do |c|
|
|
2
4
|
c.syntax = 'ipa build [options]'
|
|
3
5
|
c.summary = 'Create a new .ipa file for your app'
|
|
@@ -9,6 +11,8 @@ command :build do |c|
|
|
|
9
11
|
c.option '-s', '--scheme SCHEME', 'Scheme used to build app'
|
|
10
12
|
c.option '--[no-]clean', 'Clean project before building'
|
|
11
13
|
c.option '--[no-]archive', 'Archive project after building'
|
|
14
|
+
c.option '-d', '--destination DESTINATION', 'Destination. Defaults to current directory'
|
|
15
|
+
c.option '-m', '--embed PROVISION', 'Sign .ipa file with .mobileprovision'
|
|
12
16
|
|
|
13
17
|
c.action do |args, options|
|
|
14
18
|
validate_xcode_version!
|
|
@@ -20,6 +24,8 @@ command :build do |c|
|
|
|
20
24
|
|
|
21
25
|
@scheme = options.scheme
|
|
22
26
|
@configuration = options.configuration
|
|
27
|
+
@destination = options.destination || Dir.pwd
|
|
28
|
+
FileUtils.mkdir_p(@destination) unless File.directory?(@destination)
|
|
23
29
|
|
|
24
30
|
determine_workspace_or_project! unless @workspace || @project
|
|
25
31
|
|
|
@@ -33,12 +39,24 @@ command :build do |c|
|
|
|
33
39
|
|
|
34
40
|
log "xcodebuild", (@workspace || @project)
|
|
35
41
|
|
|
42
|
+
@configuration = options.configuration
|
|
43
|
+
|
|
36
44
|
flags = []
|
|
37
45
|
flags << "-sdk iphoneos"
|
|
38
46
|
flags << "-workspace '#{@workspace}'" if @workspace
|
|
39
47
|
flags << "-project '#{@project}'" if @project
|
|
40
48
|
flags << "-scheme '#{@scheme}'" if @scheme
|
|
41
|
-
flags << "-configuration '#{@configuration}'"
|
|
49
|
+
flags << "-configuration '#{@configuration}'" if @configuration
|
|
50
|
+
|
|
51
|
+
@target, @xcodebuild_settings = Shenzhen::XcodeBuild.settings(*flags).detect{|target, settings| settings['WRAPPER_EXTENSION'] == "app"}
|
|
52
|
+
say_error "App settings could not be found." and abort unless @xcodebuild_settings
|
|
53
|
+
|
|
54
|
+
if !@configuration
|
|
55
|
+
@configuration = @xcodebuild_settings['CONFIGURATION']
|
|
56
|
+
flags << "-configuration '#{@configuration}'"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
say_warning "Building \"#{@workspace || @project}\" with Scheme \"#{@scheme}\" and Configuration \"#{@configuration}\"\n" unless options.quiet
|
|
42
60
|
|
|
43
61
|
actions = []
|
|
44
62
|
actions << :clean unless options.clean == false
|
|
@@ -53,17 +71,17 @@ command :build do |c|
|
|
|
53
71
|
|
|
54
72
|
@app_path = File.join(@xcodebuild_settings['BUILT_PRODUCTS_DIR'], @xcodebuild_settings['WRAPPER_NAME'])
|
|
55
73
|
@dsym_path = @app_path + ".dSYM"
|
|
56
|
-
@dsym_filename = "#{@xcodebuild_settings['WRAPPER_NAME']}.dSYM"
|
|
74
|
+
@dsym_filename = File.expand_path("#{@xcodebuild_settings['WRAPPER_NAME']}.dSYM", @destination)
|
|
57
75
|
@ipa_name = @xcodebuild_settings['WRAPPER_NAME'].gsub(@xcodebuild_settings['WRAPPER_SUFFIX'], "") + ".ipa"
|
|
58
|
-
@ipa_path = File.
|
|
76
|
+
@ipa_path = File.expand_path(@ipa_name, @destination)
|
|
59
77
|
|
|
60
78
|
log "xcrun", "PackageApplication"
|
|
61
|
-
abort unless system %{xcrun -sdk iphoneos PackageApplication -v "#{@app_path}" -o "#{@ipa_path}" --embed "#{@dsym_path}" 1> /dev/null}
|
|
79
|
+
abort unless system %{xcrun -sdk iphoneos PackageApplication -v "#{@app_path}" -o "#{@ipa_path}" --embed "#{options.embed || @dsym_path}" 1> /dev/null}
|
|
62
80
|
|
|
63
81
|
log "zip", @dsym_filename
|
|
64
|
-
abort unless system %{cp -r "#{@dsym_path}"
|
|
82
|
+
abort unless system %{cp -r "#{@dsym_path}" "#{@destination}" && zip -r "#{@dsym_filename}.zip" "#{@dsym_filename}" >/dev/null && rm -rf "#{@dsym_filename}"}
|
|
65
83
|
|
|
66
|
-
say_ok "#{
|
|
84
|
+
say_ok "#{@ipa_path} successfully built" unless options.quiet
|
|
67
85
|
end
|
|
68
86
|
|
|
69
87
|
private
|
data/lib/shenzhen/plugins/ftp.rb
CHANGED
|
@@ -1,45 +1,42 @@
|
|
|
1
1
|
require 'net/ftp'
|
|
2
|
+
require 'net/sftp'
|
|
2
3
|
|
|
3
4
|
module Shenzhen::Plugins
|
|
4
5
|
module FTP
|
|
5
6
|
class Client
|
|
6
7
|
|
|
7
|
-
def initialize(host, user,
|
|
8
|
-
@host, @user, @password = host, user,
|
|
9
|
-
|
|
10
|
-
@connection = Net::FTP.new
|
|
11
|
-
@connection.passive = true
|
|
12
|
-
@connection.connect(@host)
|
|
8
|
+
def initialize(host, user, password)
|
|
9
|
+
@host, @user, @password = host, user, password
|
|
13
10
|
end
|
|
14
11
|
|
|
15
|
-
def
|
|
12
|
+
def upload(ipa, options = {})
|
|
13
|
+
connection = Net::FTP.new
|
|
14
|
+
connection.passive = true
|
|
15
|
+
connection.connect(@host)
|
|
16
|
+
|
|
16
17
|
path = expand_path_with_substitutions_from_ipa_plist(ipa, options[:path])
|
|
17
18
|
|
|
18
19
|
begin
|
|
19
|
-
|
|
20
|
+
connection.login(@user, @password) rescue raise "Login authentication failed"
|
|
20
21
|
|
|
21
22
|
if options[:mkdir]
|
|
22
|
-
components, pwd = path.split(/\//), nil
|
|
23
|
+
components, pwd = path.split(/\//).reject(&:empty?), nil
|
|
23
24
|
components.each do |component|
|
|
24
25
|
pwd = File.join(*[pwd, component].compact)
|
|
25
26
|
|
|
26
27
|
begin
|
|
27
|
-
|
|
28
|
+
connection.mkdir pwd
|
|
28
29
|
rescue => exception
|
|
29
30
|
raise exception unless /File exists/ === exception.message
|
|
30
31
|
end
|
|
31
32
|
end
|
|
32
33
|
end
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if dsym = options.delete(:dsym)
|
|
38
|
-
@connection.putbinaryfile dsym, File.basename(dsym)
|
|
39
|
-
end
|
|
40
|
-
|
|
34
|
+
|
|
35
|
+
connection.chdir path unless path.empty?
|
|
36
|
+
connection.putbinaryfile ipa, File.basename(ipa)
|
|
37
|
+
connection.putbinaryfile(options[:dsym], File.basename(options[:dsym])) if options[:dsym]
|
|
41
38
|
ensure
|
|
42
|
-
|
|
39
|
+
connection.close
|
|
43
40
|
end
|
|
44
41
|
end
|
|
45
42
|
|
|
@@ -68,6 +65,26 @@ module Shenzhen::Plugins
|
|
|
68
65
|
end
|
|
69
66
|
end
|
|
70
67
|
end
|
|
68
|
+
|
|
69
|
+
module SFTP
|
|
70
|
+
class Client < Shenzhen::Plugins::FTP::Client
|
|
71
|
+
def upload(ipa, options = {})
|
|
72
|
+
session = Net::SSH.start(@host, @user, :password => @password)
|
|
73
|
+
connection = Net::SFTP::Session.new(session).connect!
|
|
74
|
+
|
|
75
|
+
path = expand_path_with_substitutions_from_ipa_plist(ipa, options[:path])
|
|
76
|
+
|
|
77
|
+
begin
|
|
78
|
+
connection.mkdir! path if options[:mkdir]
|
|
79
|
+
connection.upload! ipa, "#{path}/#{File.basename(ipa)}"
|
|
80
|
+
connection.upload! options[:dsym], "#{path}/#{File.basename(options[:dsym])}" if options[:dsym]
|
|
81
|
+
ensure
|
|
82
|
+
connection.close_channel
|
|
83
|
+
session.shutdown!
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
71
88
|
end
|
|
72
89
|
|
|
73
90
|
command :'distribute:ftp' do |c|
|
|
@@ -83,15 +100,17 @@ command :'distribute:ftp' do |c|
|
|
|
83
100
|
c.option '-u', '--user USER', "FTP user"
|
|
84
101
|
c.option '-p', '--password PASS', "FTP password"
|
|
85
102
|
c.option '-P', '--path PATH', "FTP path. Values from Info.plist will be substituded for keys wrapped in {} \n\t\t eg. \"/path/to/folder/{CFBundleVersion}/\" could be evaluated as \"/path/to/folder/1.0.0/\""
|
|
103
|
+
c.option '--protocol [PROTOCOL]', [:ftp, :sftp], "Protocol to use (ftp, sftp)"
|
|
86
104
|
c.option '--[no-]mkdir', "Create directories on FTP if they don't already exist"
|
|
87
105
|
|
|
88
106
|
c.action do |args, options|
|
|
107
|
+
options.default :mkdir => true
|
|
89
108
|
|
|
90
109
|
determine_file! unless @file = options.file
|
|
91
110
|
say_error "Missing or unspecified .ipa file" and abort unless @file and File.exist?(@file)
|
|
92
111
|
|
|
93
112
|
determine_dsym! unless @dsym = options.dsym
|
|
94
|
-
|
|
113
|
+
say_warning "Specified dSYM.zip file doesn't exist" unless @dsym and File.exist?(@dsym)
|
|
95
114
|
|
|
96
115
|
determine_host! unless @host = options.host
|
|
97
116
|
say_error "Missing FTP host" and abort unless @host
|
|
@@ -104,10 +123,15 @@ command :'distribute:ftp' do |c|
|
|
|
104
123
|
|
|
105
124
|
@path = options.path || ""
|
|
106
125
|
|
|
107
|
-
client =
|
|
126
|
+
client = case options.protocol
|
|
127
|
+
when :sftp
|
|
128
|
+
Shenzhen::Plugins::SFTP::Client.new(@host, @user, @password)
|
|
129
|
+
else
|
|
130
|
+
Shenzhen::Plugins::FTP::Client.new(@host, @user, @password)
|
|
131
|
+
end
|
|
108
132
|
|
|
109
133
|
begin
|
|
110
|
-
client.
|
|
134
|
+
client.upload @file, {:path => @path, :dsym => @dsym, :mkdir => !!options.mkdir}
|
|
111
135
|
say_ok "Build successfully uploaded to FTP" unless options.quiet
|
|
112
136
|
rescue => exception
|
|
113
137
|
say_error "Error while uploading to FTP: #{exception}"
|
|
@@ -128,3 +152,5 @@ command :'distribute:ftp' do |c|
|
|
|
128
152
|
@password ||= password "Password:"
|
|
129
153
|
end
|
|
130
154
|
end
|
|
155
|
+
|
|
156
|
+
alias_command :'distribute:sftp', :'distribute:ftp', '--protocol', 'sftp'
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'json'
|
|
1
2
|
require 'openssl'
|
|
2
3
|
require 'faraday'
|
|
3
4
|
require 'faraday_middleware'
|
|
@@ -19,17 +20,17 @@ module Shenzhen::Plugins
|
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
def upload_build(ipa, options)
|
|
22
|
-
options[:ipa] = Faraday::UploadIO.new(ipa, 'application/octet-stream')
|
|
23
|
+
options[:ipa] = Faraday::UploadIO.new(ipa, 'application/octet-stream') if ipa and File.exist?(ipa)
|
|
23
24
|
|
|
24
25
|
if dsym_filename = options.delete(:dsym_filename)
|
|
25
26
|
options[:dsym] = Faraday::UploadIO.new(dsym_filename, 'application/octet-stream')
|
|
26
27
|
end
|
|
27
28
|
|
|
28
29
|
@connection.post do |req|
|
|
29
|
-
if options[:
|
|
30
|
+
if options[:public_identifier].nil?
|
|
30
31
|
req.url("/api/2/apps/upload")
|
|
31
32
|
else
|
|
32
|
-
req.url("/api/2/apps/#{options.delete(:
|
|
33
|
+
req.url("/api/2/apps/#{options.delete(:public_identifier)}/app_versions/upload")
|
|
33
34
|
end
|
|
34
35
|
req.headers['X-HockeyAppToken'] = @api_token
|
|
35
36
|
req.body = options
|
|
@@ -70,7 +71,7 @@ command :'distribute:hockeyapp' do |c|
|
|
|
70
71
|
say_error "Missing release notes" and abort unless @notes
|
|
71
72
|
|
|
72
73
|
parameters = {}
|
|
73
|
-
parameters[:
|
|
74
|
+
parameters[:public_identifier] = options.identifier if options.identifier
|
|
74
75
|
parameters[:notes] = @notes
|
|
75
76
|
parameters[:notes_type] = options.markdown ? "1" : "0"
|
|
76
77
|
parameters[:notify] = "1" if options.notify && !options.downloadOff
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
require 'aws-sdk'
|
|
2
|
+
|
|
3
|
+
module Shenzhen::Plugins
|
|
4
|
+
module S3
|
|
5
|
+
class Client
|
|
6
|
+
def initialize(access_key_id, secret_access_key, region)
|
|
7
|
+
@s3 = AWS::S3.new(:access_key_id => access_key_id,
|
|
8
|
+
:secret_access_key => secret_access_key,
|
|
9
|
+
:region => region)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def upload_build(ipa, options)
|
|
13
|
+
path = expand_path_with_substitutions_from_ipa_plist(ipa, options[:path])
|
|
14
|
+
|
|
15
|
+
@s3.buckets.create(options[:bucket]) if options[:create]
|
|
16
|
+
|
|
17
|
+
bucket = @s3.buckets[options[:bucket]]
|
|
18
|
+
|
|
19
|
+
files = []
|
|
20
|
+
files << ipa
|
|
21
|
+
files << options[:dsym]
|
|
22
|
+
files.each do |file|
|
|
23
|
+
key = File.join(path, File.basename(file))
|
|
24
|
+
bucket.objects.create(key, File.open(file), :acl => options[:acl])
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def expand_path_with_substitutions_from_ipa_plist(ipa, path)
|
|
31
|
+
components = []
|
|
32
|
+
|
|
33
|
+
substitutions = path.scan(/\{CFBundle[^}]+\}/)
|
|
34
|
+
return path if substitutions.empty?
|
|
35
|
+
|
|
36
|
+
Dir.mktmpdir do |dir|
|
|
37
|
+
system "unzip -q #{ipa} -d #{dir} 2> /dev/null"
|
|
38
|
+
|
|
39
|
+
plist = Dir["#{dir}/**/Info.plist"].last
|
|
40
|
+
|
|
41
|
+
substitutions.uniq.each do |substitution|
|
|
42
|
+
key = substitution[1...-1]
|
|
43
|
+
value = Shenzhen::PlistBuddy.print(plist, key)
|
|
44
|
+
|
|
45
|
+
path.gsub!(Regexp.new(substitution), value) if value
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
return path
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
command :'distribute:s3' do |c|
|
|
56
|
+
c.syntax = "ipa distribute:s3 [options]"
|
|
57
|
+
c.summary = "Distribute an .ipa file over Amazon S3"
|
|
58
|
+
c.description = ""
|
|
59
|
+
|
|
60
|
+
c.example '', '$ ipa distribute:s3 -f ./file.ipa -a accesskeyid --bucket bucket-name'
|
|
61
|
+
|
|
62
|
+
c.option '-f', '--file FILE', ".ipa file for the build"
|
|
63
|
+
c.option '-d', '--dsym FILE', "zipped .dsym package for the build"
|
|
64
|
+
c.option '-a', '--access-key-id ACCESS_KEY_ID', "AWS Access Key ID"
|
|
65
|
+
c.option '-s', '--secret-access-key SECRET_ACCESS_KEY', "AWS Secret Access Key"
|
|
66
|
+
c.option '-b', '--bucket BUCKET', "S3 bucket"
|
|
67
|
+
c.option '--[no-]create', "Create bucket if it doesn't already exist"
|
|
68
|
+
c.option '-r', '--region REGION', "Optional AWS region (for bucket creation)"
|
|
69
|
+
c.option '--acl ACL', "Uploaded object permissions e.g public_read (default), private, public_read_write, authenticated_read"
|
|
70
|
+
c.option '--source-dir SOURCE', "Optional source directory e.g. ./build"
|
|
71
|
+
c.option '-P', '--path PATH', "S3 'path'. Values from Info.plist will be substituded for keys wrapped in {} \n\t\t eg. \"/path/to/folder/{CFBundleVersion}/\" could be evaluated as \"/path/to/folder/1.0.0/\""
|
|
72
|
+
|
|
73
|
+
c.action do |args, options|
|
|
74
|
+
Dir.chdir(options.source_dir) if options.source_dir
|
|
75
|
+
|
|
76
|
+
determine_file! unless @file = options.file
|
|
77
|
+
say_error "Missing or unspecified .ipa file" and abort unless @file and File.exist?(@file)
|
|
78
|
+
|
|
79
|
+
determine_dsym! unless @dsym = options.dsym
|
|
80
|
+
say_error "Specified dSYM.zip file doesn't exist" unless @dsym and File.exist?(@dsym)
|
|
81
|
+
|
|
82
|
+
determine_access_key_id! unless @access_key_id = options.access_key_id
|
|
83
|
+
say_error "Missing AWS Access Key ID" and abort unless @access_key_id
|
|
84
|
+
|
|
85
|
+
determine_secret_access_key! unless @secret_access_key = options.secret_access_key
|
|
86
|
+
say_error "Missing AWS Secret Access Key" and abort unless @secret_access_key
|
|
87
|
+
|
|
88
|
+
determine_bucket! unless @bucket = options.bucket
|
|
89
|
+
say_error "Missing bucket" and abort unless @bucket
|
|
90
|
+
|
|
91
|
+
determine_region! unless @region = options.region
|
|
92
|
+
say_error "Missing region" and abort unless @region
|
|
93
|
+
|
|
94
|
+
determine_acl! unless @acl = options.acl
|
|
95
|
+
say_error "Missing ACL" and abort unless @acl
|
|
96
|
+
|
|
97
|
+
@path = options.path || ""
|
|
98
|
+
|
|
99
|
+
client = Shenzhen::Plugins::S3::Client.new(@access_key_id, @secret_access_key, @region)
|
|
100
|
+
|
|
101
|
+
begin
|
|
102
|
+
client.upload_build @file, {:bucket => @bucket, :create => !!options.create, :acl => @acl, :dsym => @dsym, :path => @path}
|
|
103
|
+
say_ok "Build successfully uploaded to S3" unless options.quiet
|
|
104
|
+
rescue => exception
|
|
105
|
+
say_error "Error while uploading to S3: #{exception}"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
private
|
|
110
|
+
|
|
111
|
+
def determine_access_key_id!
|
|
112
|
+
@access_key_id ||= ENV['AWS_ACCESS_KEY_ID']
|
|
113
|
+
@access_key_id ||= ask "Access Key ID:"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def determine_secret_access_key!
|
|
117
|
+
@secret_access_key ||= ENV['AWS_SECRET_ACCESS_KEY']
|
|
118
|
+
@secret_access_key ||= secret_access_key "Secret Access Key:"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def determine_bucket!
|
|
122
|
+
@bucket ||= ENV['S3_BUCKET']
|
|
123
|
+
@bucket ||= ask "S3 Bucket:"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def determine_region!
|
|
127
|
+
@region ||= ENV['AWS_REGION'] || ""
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def determine_acl!
|
|
131
|
+
@acl ||= "public_read"
|
|
132
|
+
end
|
|
133
|
+
end
|
data/nada.ipa
ADDED
|
File without changes
|
data/shenzhen.gemspec
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
2
|
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
|
|
3
4
|
require "shenzhen"
|
|
4
5
|
|
|
5
6
|
Gem::Specification.new do |s|
|
|
@@ -17,6 +18,8 @@ Gem::Specification.new do |s|
|
|
|
17
18
|
s.add_dependency "faraday", "~> 0.8"
|
|
18
19
|
s.add_dependency "faraday_middleware", "~> 0.9"
|
|
19
20
|
s.add_dependency "dotenv", "~> 0.7"
|
|
21
|
+
s.add_dependency "aws-sdk", "~> 1.0"
|
|
22
|
+
s.add_dependency "net-sftp", "~> 2.1.2"
|
|
20
23
|
|
|
21
24
|
s.add_development_dependency "rspec"
|
|
22
25
|
s.add_development_dependency "rake"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shenzhen
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mattt Thompson
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2013-
|
|
11
|
+
date: 2013-10-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: commander
|
|
@@ -80,32 +80,60 @@ dependencies:
|
|
|
80
80
|
- - ~>
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '0.7'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: aws-sdk
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ~>
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '1.0'
|
|
90
|
+
type: :runtime
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ~>
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '1.0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: net-sftp
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ~>
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: 2.1.2
|
|
104
|
+
type: :runtime
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ~>
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: 2.1.2
|
|
83
111
|
- !ruby/object:Gem::Dependency
|
|
84
112
|
name: rspec
|
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
|
86
114
|
requirements:
|
|
87
|
-
- -
|
|
115
|
+
- - '>='
|
|
88
116
|
- !ruby/object:Gem::Version
|
|
89
117
|
version: '0'
|
|
90
118
|
type: :development
|
|
91
119
|
prerelease: false
|
|
92
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
121
|
requirements:
|
|
94
|
-
- -
|
|
122
|
+
- - '>='
|
|
95
123
|
- !ruby/object:Gem::Version
|
|
96
124
|
version: '0'
|
|
97
125
|
- !ruby/object:Gem::Dependency
|
|
98
126
|
name: rake
|
|
99
127
|
requirement: !ruby/object:Gem::Requirement
|
|
100
128
|
requirements:
|
|
101
|
-
- -
|
|
129
|
+
- - '>='
|
|
102
130
|
- !ruby/object:Gem::Version
|
|
103
131
|
version: '0'
|
|
104
132
|
type: :development
|
|
105
133
|
prerelease: false
|
|
106
134
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
135
|
requirements:
|
|
108
|
-
- -
|
|
136
|
+
- - '>='
|
|
109
137
|
- !ruby/object:Gem::Version
|
|
110
138
|
version: '0'
|
|
111
139
|
description: CLI for Building & Distributing iOS Apps (.ipa Files)
|
|
@@ -124,10 +152,12 @@ files:
|
|
|
124
152
|
- ./lib/shenzhen/plistbuddy.rb
|
|
125
153
|
- ./lib/shenzhen/plugins/ftp.rb
|
|
126
154
|
- ./lib/shenzhen/plugins/hockeyapp.rb
|
|
155
|
+
- ./lib/shenzhen/plugins/s3.rb
|
|
127
156
|
- ./lib/shenzhen/plugins/testflight.rb
|
|
128
157
|
- ./lib/shenzhen/xcodebuild.rb
|
|
129
158
|
- ./lib/shenzhen.rb
|
|
130
159
|
- ./LICENSE
|
|
160
|
+
- ./nada.ipa
|
|
131
161
|
- ./Rakefile
|
|
132
162
|
- ./README.md
|
|
133
163
|
- ./shenzhen.gemspec
|
|
@@ -141,12 +171,12 @@ require_paths:
|
|
|
141
171
|
- lib
|
|
142
172
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
143
173
|
requirements:
|
|
144
|
-
- -
|
|
174
|
+
- - '>='
|
|
145
175
|
- !ruby/object:Gem::Version
|
|
146
176
|
version: '0'
|
|
147
177
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
178
|
requirements:
|
|
149
|
-
- -
|
|
179
|
+
- - '>='
|
|
150
180
|
- !ruby/object:Gem::Version
|
|
151
181
|
version: '0'
|
|
152
182
|
requirements: []
|