dpl 1.7.12.travis.742.4 → 1.7.12.travis.748.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NTA2ZjVlMzYxNWY4YWJhOTc0MDYyNTkyYTRlZjQ3YWRmODljYjY4Mw==
4
+ NGI1NmM1NTEzMjg0MjBjZWI3MWM0ZmZkYThlNjlkYmJkYmU3MDZiNA==
5
5
  data.tar.gz: !binary |-
6
- YWRkNzBiMDZhN2ZhZDdhMDM5YTFlYjQwM2E4ZmQyMGU2YzdkNTBjMQ==
6
+ YzM0YmEyNTcyOTJhOWU4ZmIxYTIyNzMwM2U0NWEwMTI0YjBmNGFkNw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NmUwZWY2NWZlOTgwZDQyYjQyZWNmMGFmYmE2MjAyMDBiYjFjMWM1Yzc5NmUz
10
- NzE2MzBkNDI0ZTY4NzI2YTIzMjdiZjg2OTc4NzE3MGVlZmI0Nzk0MWE5MTg0
11
- ZTk3YmFkMTI2NWY2MGZlMzQwOGU5NGJhNjg1ZGRjMjRiZjJmZGE=
9
+ MGI2MjBmZWU2YzNhZjVlZWExY2YyNDdjZjI1OGNmYjAzODQ0NTVhYjE5NDE2
10
+ MWJhMTI1YTMxMGM4N2MwY2UyY2Q2NmQxZDg5YTBkMDcyZmNmNjg5YmU3YjZk
11
+ MWUxMWQ3NDg3YTZmMWQxYTk3MjFiYzI3OGE4MTVhM2VkMGU5MDA=
12
12
  data.tar.gz: !binary |-
13
- ODUzM2RiMmIwNmVhYjkzZDczOTNhZWZlYWUwODQ0OTI2MDdkMzYzYTliYjc3
14
- ZTBhYmM2ZTQ2ZWZhZDVjYTFjZTUwOGIzYjMzYjZmMzQ1NjA0YmNjYmExZmRk
15
- ZmZjMjlhZTIwOTE1NTc0NTlhZDIzY2FhOGU0NzljOGI2M2RjM2M=
13
+ ZDYwNTdlNzk4ZTg2NjhjNzYxZjllZDVlODU0ZTg1NDQ1N2E4MjVmYmNiYmVl
14
+ NGRmNWIxYzkxZGViODcwODM0N2RiZDEwNGQ5NDgzNTZjYWJiMjMxMzUzM2Y5
15
+ MjYxOGYyZWI0ZTQzYjJlODExNTI1YWIyMGMyM2NlZjdlYjc2OWE=
data/README.md CHANGED
@@ -33,6 +33,7 @@ Dpl supports the following providers:
33
33
  * [packagecloud](#packagecloud)
34
34
  * [Chef Supermarket](#chef-supermarket)
35
35
  * [Lambda](#lambda)
36
+ * [TestFairy](#testfairy)
36
37
 
37
38
  ## Installation:
38
39
 
@@ -50,8 +51,6 @@ Running dpl in a terminal that saves history is insecure as your password/api ke
50
51
  ###Global Flags
51
52
  * `--provider=<provider>` sets the provider you want to deploy to. Every provider has slightly different flags, which are documented in the section about your provider following.
52
53
  * Dpl will deploy by default from the latest commit. Use the `--skip_cleanup` flag to deploy from the current file state. Note that many providers deploy by git and could ignore this option.
53
-
54
-
55
54
  ### Heroku:
56
55
 
57
56
  #### Options:
@@ -492,3 +491,33 @@ Deploy contents of a specific directory using specific module name:
492
491
  --module_name="copy" \
493
492
  --handler_name="handler";
494
493
  ```
494
+
495
+ ### TestFairy:
496
+
497
+ Your Android(apk)/iOS(ipa) file will be uploaded to TestFairy,
498
+ and your testers can start testing your app.
499
+
500
+ #### Options:
501
+ * **api-key**: TestFairy API Key (https://app.testfairy.com/settings/) run "travis encrypt --add deploy.api-key" on your repo.
502
+ * **app-file**: Path to the app file that will be generated after the build (APK/IPA).
503
+ * **symbols-file**: Path to the symbols file.
504
+ * **keystore-file**: Path to your keystore-file (must, only for android). http://docs.travis-ci.com/user/encrypting-files/
505
+ * **storepass**: storepass (must, only for android).
506
+ * **alias**: alias (must, only for android).
507
+ * **testers-groups**: You can set a tester group to be notified about this build (group1,group1).
508
+ * **notify**: If true, an email you a changelog will be sent to your users.
509
+ * **auto-update**: If true, all the previous installations of this app will be automatically all upgraded to this version.
510
+ * **video-quality**: Video quality settings, "high", "medium" or "low". Default is "high".
511
+ * **screenshot-interval**: You can choose "1"\"2"\"10" sec.
512
+ * **max-duration**: Maximum session recording length, eg "20m" or "1h". Default is "10m". Maximum "24h".
513
+ * **advanced-options**: For example (option1,option2)
514
+ * **data-only-wifi**: If true, video and recorded metrics will be sent only when connected to a wifi network.
515
+ * **record-on-background**: If true, data will be collected while the app on background.
516
+ * **video**: If true, Video recording settings "true", "false". Default is "true".
517
+ * **icon-watermark**: Add a small watermark to app icon. Default is "false".
518
+ * **metrics**: Comma-separated list of metrics to record. View list on http://docs.testfairy.com/Upload_API.html.
519
+
520
+ #### Examples:
521
+
522
+ dpl --provider=testfairy --api-key=<api-key> --app-file="out/Sample.apk" --keystore-file="out/keystore" --storepass=<storepass> --alias=<alias>
523
+
@@ -37,6 +37,7 @@ module DPL
37
37
  autoload :PuppetForge, 'dpl/provider/puppet_forge'
38
38
  autoload :Packagecloud, 'dpl/provider/packagecloud'
39
39
  autoload :ChefSupermarket, 'dpl/provider/chef_supermarket'
40
+ autoload :TestFairy, 'dpl/provider/testfairy'
40
41
 
41
42
 
42
43
  def self.new(context, options)
@@ -0,0 +1,184 @@
1
+ module DPL
2
+ class Provider
3
+ class TestFairy < Provider
4
+
5
+ require "net/http"
6
+ require 'net/http/post/multipart'
7
+ require 'json'
8
+ require 'tempfile'
9
+
10
+
11
+ VERSION = "0.1"
12
+ TAG = "-TestFairy-"
13
+ SERVER = "http://api.testfairy.com"
14
+ UPLOAD_URL_PATH = "/api/upload";
15
+ UPLOAD_SIGNED_URL_PATH = "/api/upload-signed";
16
+
17
+ def check_auth
18
+ if android?
19
+ storepassToPrint = option(:storepass).clone
20
+ aliasToPrint = option(:alias).clone
21
+ puts "keystore-file = #{option(:keystore_file)} storepass = #{storepassToPrint.sub! storepassToPrint[1..-2], '****'} alias = #{aliasToPrint.sub! aliasToPrint[1..-2], '****'}"
22
+ end
23
+ puts "api-key = #{option(:api_key).gsub(/[123456789]/, '*')} symbols-file = #{options[:symbols_file]}"
24
+ end
25
+
26
+ def needs_key?
27
+ false
28
+ end
29
+
30
+ def push_app
31
+ puts "push_app #{TAG}"
32
+ response = upload_app
33
+ if android?
34
+ puts response['instrumented_url']
35
+ instrumentedFile = download_from_url response['instrumented_url']
36
+ signedApk = signing_apk instrumentedFile
37
+ response = upload_signed_apk signedApk
38
+ end
39
+ puts "Upload success!, check your build on #{response['build_url']}"
40
+ end
41
+
42
+ def android?
43
+ option(:app_file).include? "apk"
44
+ end
45
+
46
+
47
+ private
48
+
49
+ def signing_apk(instrumentedFile)
50
+ signed = Tempfile.new(['instrumented-signed', '.apk'])
51
+ zipOutput = %x[#{zip_path} -qd #{instrumentedFile} META-INF/*]
52
+ if zipOutput.include? 'error'
53
+ raise Error, zipOutput
54
+ end
55
+
56
+ jarSignerOutput = %x[#{jarsigner_path} -keystore #{option(:keystore_file)} -storepass #{option(:storepass)} -digestalg SHA1 -sigalg MD5withRSA #{instrumentedFile} #{option(:alias)}]
57
+ if jarSignerOutput.include? 'error'
58
+ raise Error, jarSignerOutput
59
+ end
60
+
61
+ verifyOutput = %x[#{jarsigner_path} -verify #{instrumentedFile}]
62
+ if !verifyOutput.include? 'jar verified'
63
+ raise Error, verifyOutput
64
+ end
65
+
66
+ zipAlignOutput = %x[#{zipalign_path} -f 4 #{instrumentedFile} #{signed.path}]
67
+
68
+ puts "signing Apk finished: #{signed.path()} (file size:#{File.size(signed.path())} )"
69
+ signed.path()
70
+ end
71
+
72
+ def download_from_url(url)
73
+ puts "downloading from #{url} "
74
+ uri = URI.parse(url)
75
+ instrumentedFile = Net::HTTP.start(uri.host, uri.port) do |http|
76
+ resp = http.get(uri.path)
77
+ file = Tempfile.new(['instrumented', '.apk'])
78
+ file.write(resp.body)
79
+ file.flush
80
+ file
81
+ end
82
+ puts "Done #{instrumentedFile.path()} (file size:#{File.size(instrumentedFile.path())} )"
83
+ instrumentedFile.path()
84
+ end
85
+
86
+ def upload_app
87
+ uploadUrl = SERVER + UPLOAD_URL_PATH
88
+ params = get_params
89
+ post uploadUrl, params
90
+ end
91
+
92
+ def upload_signed_apk apkPath
93
+ uploadSignedUrl = SERVER + UPLOAD_SIGNED_URL_PATH
94
+
95
+ params = {"api_key" => "#{option(:api_key)}"}
96
+ add_file_param params , 'apk_file', apkPath
97
+ add_file_param params, 'symbols_file', options[:symbols_file]
98
+ add_param params, 'testers-groups', options[:testers_groups]
99
+ add_boolean_param params, 'notify', options[:notify]
100
+ add_boolean_param params, 'auto-update', options[:auto_update]
101
+
102
+ post uploadSignedUrl, params
103
+ end
104
+
105
+ def post url, params
106
+ puts "Upload parameters = #{get_printable_params params} \nto #{url}"
107
+ uri = URI.parse(url)
108
+ request = Net::HTTP::Post::Multipart.new(uri.path, params, 'User-Agent' => "Travis plugin version=#{VERSION}")
109
+ res = Net::HTTP.start(uri.host, uri.port) do |http|
110
+ http.request(request)
111
+ end
112
+ puts res.body
113
+ resBody = JSON.parse(res.body)
114
+ if (resBody['status'] == 'fail')
115
+ raise Error, resBody['message']
116
+ end
117
+ return resBody
118
+ end
119
+
120
+ def get_printable_params params
121
+ paramsToPrint = params.clone
122
+ paramsToPrint['api_key'] = paramsToPrint['api_key'].gsub(/[123456789]/, '*')
123
+ paramsToPrint['apk_file'] = paramsToPrint['apk_file'].path()
124
+ JSON.pretty_generate(paramsToPrint)
125
+ end
126
+
127
+ def get_params
128
+ params = {'api_key' => "#{option(:api_key)}"}
129
+ add_file_param params, 'apk_file', option(:app_file)
130
+ add_file_param params, 'symbols_file', options[:symbols_file]
131
+ add_param params, 'video-quality', options[:video_quality]
132
+ add_param params, 'screenshot-interval', options[:screenshot_interval]
133
+ add_param params, 'max-duration', options[:max_duration]
134
+ add_param params, 'testers-groups', options[:testers_groups]
135
+ add_param params, 'advanced-options', options[:advanced_options]
136
+ add_param params, 'metrics', options[:metrics]
137
+ add_boolean_param params, 'data-only-wifi', options[:data_only_wifi]
138
+ add_boolean_param params, 'record-on-background', options[:record_on_background]
139
+ add_boolean_param params, 'video', options[:video]
140
+ add_boolean_param params, 'notify', options[:notify]
141
+ add_boolean_param params, 'icon-watermark', options[:icon_watermark]
142
+
143
+ travisCommitRange = context.env.fetch('TRAVIS_COMMIT_RANGE',nil)
144
+ if !travisCommitRange.nil?
145
+ changelog = %x[git log --pretty=oneline --abbrev-commit #{travisCommitRange}]
146
+ add_param params, 'changelog', changelog
147
+ end
148
+ params
149
+ end
150
+
151
+ def add_file_param params, fileName, filePath
152
+ if (!filePath.nil? && !filePath.empty?)
153
+ params[fileName] = UploadIO.new(File.new(filePath), "", filePath.split("/").last)
154
+ end
155
+ end
156
+
157
+ def add_param params, paramName, param
158
+ if (!param.nil? && !param.empty?)
159
+ params[paramName] = param
160
+ end
161
+ end
162
+
163
+ def add_boolean_param params, paramName, param
164
+ if (!param.nil? && !param.empty?)
165
+ params[paramName] = (param == true) ? "on" : "off"
166
+ end
167
+ end
168
+
169
+ def zip_path
170
+ @zip_path ||= %x[which zip].split("\n").first
171
+ end
172
+
173
+ def zipalign_path
174
+ android_home_path = context.env.fetch('ANDROID_HOME', '/usr')
175
+ @zipalign_path ||= %x[find -L #{android_home_path} -name zipalign 2>/dev/null].split("\n").first
176
+ end
177
+
178
+ def jarsigner_path
179
+ java_home_path = context.env.fetch('JAVA_HOME', '/usr')
180
+ @jarsigner_path ||= %x[find -L #{java_home_path} -name jarsigner 2>/dev/null].split("\n").first
181
+ end
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+ require 'dpl/provider/testfairy'
3
+
4
+ describe DPL::Provider::TestFairy do
5
+
6
+ before (:all) do
7
+
8
+ %x[mkdir /tmp/android/]
9
+ %x[echo 'cp $3 $4' > /tmp/android/zipalign]
10
+ %x[chmod +x /tmp/android/zipalign]
11
+
12
+ @kyestore = '/tmp/debug.keystore'
13
+ %x[curl -Lso #{@kyestore} http://www.testfairy.com/support-files/travis/dpl/debug.keystore]
14
+
15
+ @local_android_app = '/tmp/android.apk'
16
+ %x[curl -Lso #{@local_android_app} http://www.testfairy.com/support-files/travis/dpl/android.apk]
17
+
18
+ @local_ios_app = '/tmp/ios.ipa'
19
+ %x[curl -Lso #{@local_ios_app} http://www.testfairy.com/support-files/travis/dpl/Empty.ipa]
20
+
21
+ end
22
+
23
+ let :context do
24
+ DummyContext.new
25
+ end
26
+
27
+ subject :provider do
28
+ # the account is travis-test@testfairy.com
29
+ described_class.new(context, :api_key => '4b85a2c03ba6026f4e22640a0432638180e1d1ea', :storepass => "android", :alias => "androiddebugkey", :keystore_file => @kyestore, :video => "true", :video_quality => 'low')
30
+ end
31
+
32
+ describe "#check_auth" do
33
+ example "check_auth without app_file" do
34
+ lambda {provider.check_auth}.should raise_error
35
+ end
36
+
37
+ example "check_auth with app_file" do
38
+ provider.options.update(:app_file => @local_android_app)
39
+ provider.check_auth
40
+ end
41
+ end
42
+
43
+ describe "#needs_key?" do
44
+ example do
45
+ expect(provider.needs_key?).to eq(false)
46
+ end
47
+ end
48
+
49
+ describe "#push_app" do
50
+ before do
51
+ context.stub(:env) { {'ANDROID_HOME' => '/tmp/android', 'JAVA_HOME' => '/usr/bin'} }
52
+ end
53
+
54
+ example "push_app without app_file" do
55
+ lambda {provider.push_app}.should raise_error
56
+ end
57
+
58
+ example "push_app with app_file" do
59
+ provider.options.update(:app_file => @local_android_app)
60
+ provider.push_app
61
+ end
62
+
63
+ example "push_app with wrong alias" do
64
+ provider.options.update(:app_file => @local_android_app)
65
+ provider.options.update(:alias => 'test')
66
+ lambda {provider.push_app}.should raise_error
67
+ end
68
+
69
+ example "push_app with wrong storepass" do
70
+ provider.options.update(:app_file => @local_android_app)
71
+ provider.options.update(:storepass => 'test')
72
+ lambda {provider.push_app}.should raise_error
73
+ end
74
+
75
+ example "push_app with iOS app_file" do
76
+ provider.options.update(:app_file => @local_ios_app)
77
+ provider.push_app
78
+ end
79
+ end
80
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dpl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.12.travis.742.4
4
+ version: 1.7.12.travis.748.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Haase
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-02 00:00:00.000000000 Z
11
+ date: 2015-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -136,6 +136,7 @@ files:
136
136
  - lib/dpl/provider/releases.rb
137
137
  - lib/dpl/provider/rubygems.rb
138
138
  - lib/dpl/provider/s3.rb
139
+ - lib/dpl/provider/testfairy.rb
139
140
  - lib/dpl/version.rb
140
141
  - notes/dotcloud.md
141
142
  - notes/engine_yard.md
@@ -172,6 +173,7 @@ files:
172
173
  - spec/provider/releases_spec.rb
173
174
  - spec/provider/rubygems_spec.rb
174
175
  - spec/provider/s3_spec.rb
176
+ - spec/provider/testfairy_spec.rb
175
177
  - spec/provider_spec.rb
176
178
  - spec/spec_helper.rb
177
179
  homepage: https://github.com/travis-ci/dpl