dpl-connect 1.8.43
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 +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +8 -0
- data/.rspec +2 -0
- data/.travis.yml +36 -0
- data/Gemfile +100 -0
- data/LICENSE +22 -0
- data/README.md +934 -0
- data/Rakefile +1 -0
- data/TESTING.md +29 -0
- data/bin/dpl +5 -0
- data/dpl.gemspec +32 -0
- data/lib/dpl/cli.rb +66 -0
- data/lib/dpl/error.rb +3 -0
- data/lib/dpl/provider.rb +264 -0
- data/lib/dpl/provider/anynines.rb +13 -0
- data/lib/dpl/provider/appfog.rb +21 -0
- data/lib/dpl/provider/atlas.rb +108 -0
- data/lib/dpl/provider/azure_webapps.rb +48 -0
- data/lib/dpl/provider/bintray.rb +509 -0
- data/lib/dpl/provider/bitballoon.rb +22 -0
- data/lib/dpl/provider/bluemix_cloud_foundry.rb +23 -0
- data/lib/dpl/provider/boxfuse.rb +57 -0
- data/lib/dpl/provider/catalyze.rb +49 -0
- data/lib/dpl/provider/chef_supermarket.rb +85 -0
- data/lib/dpl/provider/cloud66.rb +38 -0
- data/lib/dpl/provider/cloud_files.rb +38 -0
- data/lib/dpl/provider/cloud_foundry.rb +43 -0
- data/lib/dpl/provider/code_deploy.rb +123 -0
- data/lib/dpl/provider/deis.rb +119 -0
- data/lib/dpl/provider/divshot.rb +23 -0
- data/lib/dpl/provider/elastic_beanstalk.rb +195 -0
- data/lib/dpl/provider/engine_yard.rb +90 -0
- data/lib/dpl/provider/firebase.rb +27 -0
- data/lib/dpl/provider/gae.rb +97 -0
- data/lib/dpl/provider/gcs.rb +59 -0
- data/lib/dpl/provider/hackage.rb +29 -0
- data/lib/dpl/provider/heroku.rb +18 -0
- data/lib/dpl/provider/heroku/api.rb +98 -0
- data/lib/dpl/provider/heroku/generic.rb +94 -0
- data/lib/dpl/provider/heroku/git.rb +28 -0
- data/lib/dpl/provider/lambda.rb +236 -0
- data/lib/dpl/provider/launchpad.rb +48 -0
- data/lib/dpl/provider/modulus.rb +23 -0
- data/lib/dpl/provider/npm.rb +64 -0
- data/lib/dpl/provider/openshift.rb +59 -0
- data/lib/dpl/provider/ops_works.rb +132 -0
- data/lib/dpl/provider/packagecloud.rb +144 -0
- data/lib/dpl/provider/pages.rb +79 -0
- data/lib/dpl/provider/puppet_forge.rb +43 -0
- data/lib/dpl/provider/pypi.rb +111 -0
- data/lib/dpl/provider/releases.rb +139 -0
- data/lib/dpl/provider/rubygems.rb +51 -0
- data/lib/dpl/provider/s3.rb +123 -0
- data/lib/dpl/provider/scalingo.rb +97 -0
- data/lib/dpl/provider/script.rb +29 -0
- data/lib/dpl/provider/surge.rb +33 -0
- data/lib/dpl/provider/testfairy.rb +190 -0
- data/lib/dpl/provider/transifex.rb +45 -0
- data/lib/dpl/version.rb +3 -0
- data/notes/engine_yard.md +1 -0
- data/notes/heroku.md +3 -0
- data/spec/cli_spec.rb +36 -0
- data/spec/provider/anynines_spec.rb +20 -0
- data/spec/provider/appfog_spec.rb +35 -0
- data/spec/provider/atlas_spec.rb +99 -0
- data/spec/provider/azure_webapps_spec.rb +95 -0
- data/spec/provider/bintray_spec.rb +259 -0
- data/spec/provider/bitballoon_spec.rb +32 -0
- data/spec/provider/bluemixcloudfoundry_spec.rb +23 -0
- data/spec/provider/boxfuse_spec.rb +16 -0
- data/spec/provider/catalyze_spec.rb +39 -0
- data/spec/provider/chef_supermarket_spec.rb +51 -0
- data/spec/provider/cloud66_spec.rb +44 -0
- data/spec/provider/cloud_files_spec.rb +88 -0
- data/spec/provider/cloudfoundry_spec.rb +71 -0
- data/spec/provider/code_deploy_spec.rb +360 -0
- data/spec/provider/deis_spec.rb +116 -0
- data/spec/provider/divshot_spec.rb +28 -0
- data/spec/provider/elastic_beanstalk_spec.rb +209 -0
- data/spec/provider/firebase_spec.rb +40 -0
- data/spec/provider/gae_spec.rb +26 -0
- data/spec/provider/gcs_spec.rb +115 -0
- data/spec/provider/hackage_spec.rb +47 -0
- data/spec/provider/heroku_spec.rb +357 -0
- data/spec/provider/lambda_spec.rb +432 -0
- data/spec/provider/launchpad_spec.rb +33 -0
- data/spec/provider/modulus_spec.rb +29 -0
- data/spec/provider/npm_spec.rb +95 -0
- data/spec/provider/openshift_spec.rb +91 -0
- data/spec/provider/ops_works_spec.rb +127 -0
- data/spec/provider/packagecloud_spec.rb +56 -0
- data/spec/provider/puppet_forge_spec.rb +60 -0
- data/spec/provider/pypi_spec.rb +103 -0
- data/spec/provider/releases_spec.rb +303 -0
- data/spec/provider/rubygems_spec.rb +106 -0
- data/spec/provider/s3_spec.rb +174 -0
- data/spec/provider/scalingo_spec.rb +64 -0
- data/spec/provider/script_spec.rb +26 -0
- data/spec/provider/surge_spec.rb +15 -0
- data/spec/provider/testfairy_spec.rb +86 -0
- data/spec/provider/transifex_spec.rb +110 -0
- data/spec/provider_spec.rb +210 -0
- data/spec/spec_helper.rb +20 -0
- metadata +279 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
require 'net/http'
|
|
2
|
+
require 'uri'
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'date'
|
|
5
|
+
|
|
6
|
+
module DPL
|
|
7
|
+
class Provider
|
|
8
|
+
class Scalingo < Provider
|
|
9
|
+
|
|
10
|
+
def install_deploy_dependencies
|
|
11
|
+
unless context.shell "curl -OL https://cli-dl.scalingo.io/release/scalingo_latest_linux_amd64.tar.gz && tar -zxvf scalingo_latest_linux_amd64.tar.gz && mv scalingo_*_linux_amd64/scalingo . && rm scalingo_latest_linux_amd64.tar.gz && rm -r scalingo_*_linux_amd64"
|
|
12
|
+
error "Couldn't install Scalingo CLI."
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def initialize(context, options)
|
|
17
|
+
super
|
|
18
|
+
@options = options
|
|
19
|
+
@remote = options[:remote] || "scalingo"
|
|
20
|
+
@branch = options[:branch] || "master"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def logged_in
|
|
24
|
+
context.shell "DISABLE_INTERACTIVE=true ./scalingo login 2> /dev/null > /dev/null"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def check_auth
|
|
28
|
+
if @options[:api_key]
|
|
29
|
+
unless context.shell "mkdir -p ~/.config/scalingo"
|
|
30
|
+
error "Couldn't create authentication file."
|
|
31
|
+
end
|
|
32
|
+
url = URI.parse('http://api.scalingo.com/v1/users/self')
|
|
33
|
+
http = Net::HTTP.new(url.host, url.port)
|
|
34
|
+
request = Net::HTTP::Get.new(url.request_uri)
|
|
35
|
+
request.basic_auth("", @options[:api_key])
|
|
36
|
+
request["Accept"] = "application/json"
|
|
37
|
+
request["Content-type"] = "application/json"
|
|
38
|
+
response = http.request(request)
|
|
39
|
+
data = {}
|
|
40
|
+
if File.exist?("#{Dir.home}/.config/scalingo/auth")
|
|
41
|
+
data = JSON.parse(File.read("#{Dir.home}/.config/scalingo/auth"))
|
|
42
|
+
end
|
|
43
|
+
begin
|
|
44
|
+
user = JSON.parse(response.body)
|
|
45
|
+
rescue
|
|
46
|
+
error "Invalid API token."
|
|
47
|
+
end
|
|
48
|
+
data["auth_config_data"] = {}
|
|
49
|
+
data["auth_config_data"]["api.scalingo.com"] = {}
|
|
50
|
+
data["auth_config_data"]["api.scalingo.com"]["id"] = user["user"]["id"]
|
|
51
|
+
data["auth_config_data"]["api.scalingo.com"]["last_name"] = user["user"]["last_name"]
|
|
52
|
+
data["auth_config_data"]["api.scalingo.com"]["username"] = user["user"]["username"]
|
|
53
|
+
data["auth_config_data"]["api.scalingo.com"]["email"] = user["user"]["email"]
|
|
54
|
+
data["auth_config_data"]["api.scalingo.com"]["first_name"] = user["user"]["first_name"]
|
|
55
|
+
data["auth_config_data"]["api.scalingo.com"]["auth_token"] = @options[:api_key]
|
|
56
|
+
data["last_update"] = DateTime.now
|
|
57
|
+
f = File.open("#{Dir.home}/.config/scalingo/auth", "w+") {
|
|
58
|
+
|f| f.write(data.to_json)
|
|
59
|
+
}
|
|
60
|
+
elsif @options[:username] && @options[:password]
|
|
61
|
+
context.shell "echo -e \"#{@options[:username]}\n#{@options[:password]}\" | timeout 2 ./scalingo login 2> /dev/null > /dev/null"
|
|
62
|
+
end
|
|
63
|
+
if !logged_in
|
|
64
|
+
error "Couldn't connect to Scalingo API."
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def setup_key(file, type = nil)
|
|
69
|
+
if !logged_in
|
|
70
|
+
error "Couldn't connect to Scalingo API."
|
|
71
|
+
end
|
|
72
|
+
unless context.shell "./scalingo keys-add dpl_tmp_key #{file}"
|
|
73
|
+
error "Couldn't add ssh key."
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def remove_key
|
|
78
|
+
if !logged_in
|
|
79
|
+
error "Couldn't connect to Scalingo API."
|
|
80
|
+
end
|
|
81
|
+
unless context.shell "./scalingo keys-remove dpl_tmp_key"
|
|
82
|
+
error "Couldn't remove ssh key."
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def push_app
|
|
87
|
+
if @options[:app]
|
|
88
|
+
context.shell "git remote add #{@remote} git@scalingo.com:#{@options[:app]}.git 2> /dev/null > /dev/null"
|
|
89
|
+
end
|
|
90
|
+
unless context.shell "git push #{@remote} #{@branch} -f"
|
|
91
|
+
error "Couldn't push your app."
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module DPL
|
|
2
|
+
class Provider
|
|
3
|
+
class Script < Provider
|
|
4
|
+
|
|
5
|
+
experimental 'Script'
|
|
6
|
+
|
|
7
|
+
def check_auth
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def check_app
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def needs_key?
|
|
14
|
+
false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def push_app
|
|
18
|
+
context.shell script
|
|
19
|
+
if $?.exitstatus != 0
|
|
20
|
+
raise Error, "Script failed with status #{$?.exitstatus}"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def script
|
|
25
|
+
options[:script]
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module DPL
|
|
2
|
+
class Provider
|
|
3
|
+
class Surge < Provider
|
|
4
|
+
npm_g 'surge'
|
|
5
|
+
|
|
6
|
+
def project
|
|
7
|
+
File.expand_path( (context.env['TRAVIS_BUILD_DIR'] || '.' ) + "/" + (options[:project] || '') )
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def domain
|
|
11
|
+
options[:domain] || ''
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def check_auth
|
|
15
|
+
if ! context.env['SURGE_TOKEN'] then raise Error, "Please add SURGE_TOKEN in Travis settings (get your token with 'surge token')" end
|
|
16
|
+
if ! context.env['SURGE_LOGIN'] then raise Error, "Please add SURGE_LOGIN in Travis settings (its your email)" end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def check_app
|
|
20
|
+
if ! File.directory?(project) then raise Error, "Please set a valid project folder path in .travis.yml under deploy: project: myPath" end
|
|
21
|
+
if domain.empty? && ! File.exist?("#{project}/CNAME") then raise Error, "Please set domain in .travis.yml under deploy: project: myDomain (or in a CNAME file in the repo project folder)" end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def needs_key?
|
|
25
|
+
false
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def push_app
|
|
29
|
+
context.shell "surge #{project} #{domain}"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
module DPL
|
|
2
|
+
class Provider
|
|
3
|
+
class TestFairy < Provider
|
|
4
|
+
|
|
5
|
+
requires "multipart-post", load: 'net/http/post/multipart', version: '2.0.0'
|
|
6
|
+
|
|
7
|
+
require "net/http"
|
|
8
|
+
require 'net/http/post/multipart'
|
|
9
|
+
require 'json'
|
|
10
|
+
require 'tempfile'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
VERSION = "0.1"
|
|
14
|
+
TAG = "-TestFairy-"
|
|
15
|
+
SERVER = "http://api.testfairy.com"
|
|
16
|
+
UPLOAD_URL_PATH = "/api/upload";
|
|
17
|
+
UPLOAD_SIGNED_URL_PATH = "/api/upload-signed";
|
|
18
|
+
|
|
19
|
+
def check_auth
|
|
20
|
+
if android?
|
|
21
|
+
storepassToPrint = option(:storepass).clone
|
|
22
|
+
aliasToPrint = option(:alias).clone
|
|
23
|
+
puts "keystore-file = #{option(:keystore_file)} storepass = #{storepassToPrint.sub! storepassToPrint[1..-2], '****'} alias = #{aliasToPrint.sub! aliasToPrint[1..-2], '****'}"
|
|
24
|
+
end
|
|
25
|
+
puts "api-key = #{option(:api_key).gsub(/[123456789]/, '*')} symbols-file = #{options[:symbols_file]}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def needs_key?
|
|
29
|
+
false
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def push_app
|
|
33
|
+
puts "push_app #{TAG}"
|
|
34
|
+
response = upload_app
|
|
35
|
+
if android?
|
|
36
|
+
puts response['instrumented_url']
|
|
37
|
+
instrumentedFile = download_from_url response['instrumented_url']
|
|
38
|
+
signedApk = signing_apk instrumentedFile
|
|
39
|
+
response = upload_signed_apk signedApk
|
|
40
|
+
end
|
|
41
|
+
puts "Upload success!, check your build on #{response['build_url']}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def android?
|
|
45
|
+
option(:app_file).include? "apk"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def signing_apk(instrumentedFile)
|
|
52
|
+
signed = Tempfile.new(['instrumented-signed', '.apk'])
|
|
53
|
+
zipOutput = %x[#{zip_path} -qd #{instrumentedFile} META-INF/*]
|
|
54
|
+
if zipOutput.include? 'error'
|
|
55
|
+
raise Error, zipOutput
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
jarSignerOutput = %x[#{jarsigner_path} -keystore #{option(:keystore_file)} -storepass #{option(:storepass)} -digestalg SHA1 -sigalg MD5withRSA #{instrumentedFile} #{option(:alias)}]
|
|
59
|
+
if jarSignerOutput.include? 'error'
|
|
60
|
+
raise Error, jarSignerOutput
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
verifyOutput = %x[#{jarsigner_path} -verify #{instrumentedFile}]
|
|
64
|
+
if !verifyOutput.include? 'jar verified'
|
|
65
|
+
raise Error, verifyOutput
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
zipAlignOutput = %x[#{zipalign_path} -f 4 #{instrumentedFile} #{signed.path}]
|
|
69
|
+
|
|
70
|
+
puts "signing Apk finished: #{signed.path()} (file size:#{File.size(signed.path())} )"
|
|
71
|
+
signed.path()
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def download_from_url(url)
|
|
75
|
+
puts "downloading from #{url} "
|
|
76
|
+
url = "#{url}?api_key=#{option(:api_key)}"
|
|
77
|
+
uri = URI.parse(url)
|
|
78
|
+
instrumentedFile = Net::HTTP.start(uri.host, uri.port) do |http|
|
|
79
|
+
resp = http.get "#{uri.path}?#{uri.query}"
|
|
80
|
+
if resp.code == "302"
|
|
81
|
+
resp = Net::HTTP.get_response(URI.parse(resp.header['location']))
|
|
82
|
+
end
|
|
83
|
+
file = Tempfile.new(['instrumented', '.apk'])
|
|
84
|
+
file.write(resp.body)
|
|
85
|
+
file.flush
|
|
86
|
+
file
|
|
87
|
+
end
|
|
88
|
+
puts "Done #{instrumentedFile.path()} (file size:#{File.size(instrumentedFile.path())} )"
|
|
89
|
+
instrumentedFile.path()
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def upload_app
|
|
93
|
+
uploadUrl = SERVER + UPLOAD_URL_PATH
|
|
94
|
+
params = get_params
|
|
95
|
+
post uploadUrl, params
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def upload_signed_apk apkPath
|
|
99
|
+
uploadSignedUrl = SERVER + UPLOAD_SIGNED_URL_PATH
|
|
100
|
+
|
|
101
|
+
params = {"api_key" => "#{option(:api_key)}"}
|
|
102
|
+
add_file_param params , 'apk_file', apkPath
|
|
103
|
+
add_file_param params, 'symbols_file', options[:symbols_file]
|
|
104
|
+
add_param params, 'testers-groups', options[:testers_groups]
|
|
105
|
+
add_boolean_param params, 'notify', options[:notify]
|
|
106
|
+
add_boolean_param params, 'auto-update', options[:auto_update]
|
|
107
|
+
|
|
108
|
+
post uploadSignedUrl, params
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def post url, params
|
|
112
|
+
puts "Upload parameters = #{get_printable_params params} \nto #{url}"
|
|
113
|
+
uri = URI.parse(url)
|
|
114
|
+
request = Net::HTTP::Post::Multipart.new(uri.path, params, 'User-Agent' => "Travis plugin version=#{VERSION}")
|
|
115
|
+
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
|
116
|
+
http.request(request)
|
|
117
|
+
end
|
|
118
|
+
puts res.body
|
|
119
|
+
resBody = JSON.parse(res.body)
|
|
120
|
+
if (resBody['status'] == 'fail')
|
|
121
|
+
raise Error, resBody['message']
|
|
122
|
+
end
|
|
123
|
+
return resBody
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def get_printable_params params
|
|
127
|
+
paramsToPrint = params.clone
|
|
128
|
+
paramsToPrint['api_key'] = paramsToPrint['api_key'].gsub(/[123456789]/, '*')
|
|
129
|
+
paramsToPrint['apk_file'] = paramsToPrint['apk_file'].path()
|
|
130
|
+
JSON.pretty_generate(paramsToPrint)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def get_params
|
|
134
|
+
params = {'api_key' => "#{option(:api_key)}"}
|
|
135
|
+
add_file_param params, 'apk_file', option(:app_file)
|
|
136
|
+
add_file_param params, 'symbols_file', options[:symbols_file]
|
|
137
|
+
add_param params, 'video-quality', options[:video_quality]
|
|
138
|
+
add_param params, 'screenshot-interval', options[:screenshot_interval]
|
|
139
|
+
add_param params, 'max-duration', options[:max_duration]
|
|
140
|
+
add_param params, 'testers-groups', options[:testers_groups]
|
|
141
|
+
add_param params, 'advanced-options', options[:advanced_options]
|
|
142
|
+
add_param params, 'metrics', options[:metrics]
|
|
143
|
+
add_boolean_param params, 'data-only-wifi', options[:data_only_wifi]
|
|
144
|
+
add_boolean_param params, 'record-on-background', options[:record_on_background]
|
|
145
|
+
add_boolean_param params, 'video', options[:video]
|
|
146
|
+
add_boolean_param params, 'notify', options[:notify]
|
|
147
|
+
add_boolean_param params, 'icon-watermark', options[:icon_watermark]
|
|
148
|
+
|
|
149
|
+
travisCommitRange = context.env.fetch('TRAVIS_COMMIT_RANGE',nil)
|
|
150
|
+
if !travisCommitRange.nil?
|
|
151
|
+
changelog = %x[git log --pretty=oneline --abbrev-commit #{travisCommitRange}]
|
|
152
|
+
add_param params, 'changelog', changelog
|
|
153
|
+
end
|
|
154
|
+
params
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def add_file_param params, fileName, filePath
|
|
158
|
+
if (!filePath.nil? && !filePath.empty?)
|
|
159
|
+
params[fileName] = UploadIO.new(File.new(filePath), "", filePath.split("/").last)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def add_param params, paramName, param
|
|
164
|
+
if (!param.nil? && !param.empty?)
|
|
165
|
+
params[paramName] = param
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def add_boolean_param params, paramName, param
|
|
170
|
+
if (!param.nil?)
|
|
171
|
+
params[paramName] = (param == true) ? "on" : "off"
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def zip_path
|
|
176
|
+
@zip_path ||= %x[which zip].split("\n").first
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def zipalign_path
|
|
180
|
+
android_home_path = context.env.fetch('ANDROID_HOME', '/usr')
|
|
181
|
+
@zipalign_path ||= %x[find -L #{android_home_path} -name zipalign 2>/dev/null].split("\n").first
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def jarsigner_path
|
|
185
|
+
java_home_path = context.env.fetch('JAVA_HOME', '/usr')
|
|
186
|
+
@jarsigner_path ||= %x[find -L #{java_home_path} -name jarsigner 2>/dev/null].split("\n").first
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module DPL
|
|
2
|
+
class Provider
|
|
3
|
+
class Transifex < Provider
|
|
4
|
+
experimental 'Transifex'
|
|
5
|
+
|
|
6
|
+
DEFAULT_CLIENT_VERSION = '>=0.11'
|
|
7
|
+
DEFAULT_HOSTNAME = 'https://www.transifex.com'
|
|
8
|
+
|
|
9
|
+
def install_deploy_dependencies
|
|
10
|
+
cli_version = options[:cli_version] || DEFAULT_CLIENT_VERSION
|
|
11
|
+
self.class.pip 'transifex', 'transifex', cli_version
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def needs_key?
|
|
15
|
+
false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def check_auth
|
|
19
|
+
install_deploy_dependencies
|
|
20
|
+
write_transifexrc
|
|
21
|
+
context.shell 'tx status'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def push_app
|
|
25
|
+
source_push
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def write_transifexrc
|
|
29
|
+
File.open(File.expand_path('~/.transifexrc'), 'w') do |f|
|
|
30
|
+
f.puts [
|
|
31
|
+
"[#{options[:hostname] || DEFAULT_HOSTNAME}]",
|
|
32
|
+
"hostname = #{options[:hostname] || DEFAULT_HOSTNAME}",
|
|
33
|
+
"username = #{options[:username]}",
|
|
34
|
+
"password = #{options[:password]}",
|
|
35
|
+
"token = #{options[:token]}",
|
|
36
|
+
].join("\n")
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def source_push
|
|
41
|
+
context.shell 'tx push --source --no-interactive', retry: true
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
data/lib/dpl/version.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
EY has a a special deploy app. Get in touch with Kevin Holler if we don't hear back from them.
|
data/notes/heroku.md
ADDED
data/spec/cli_spec.rb
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'dpl/cli'
|
|
3
|
+
|
|
4
|
+
describe DPL::CLI do
|
|
5
|
+
describe "#options" do
|
|
6
|
+
example { expect(described_class.new.options[:app]) .to eq(File.basename(Dir.pwd)) }
|
|
7
|
+
example { expect(described_class.new(:app => 'foo') .options[:app]).to eq('foo') }
|
|
8
|
+
example { expect(described_class.new("--app=foo") .options[:app]).to eq('foo') }
|
|
9
|
+
example { expect(described_class.new("--app") .options[:app]).to eq(true) }
|
|
10
|
+
example { expect(described_class.new("--app=foo", "--app=bar") .options[:app]).to eq(['foo', 'bar']) }
|
|
11
|
+
|
|
12
|
+
example "error handling" do
|
|
13
|
+
expect($stderr).to receive(:puts).with('invalid option "app"')
|
|
14
|
+
expect { described_class.new("app") }.to raise_error(SystemExit)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "#run" do
|
|
19
|
+
example "triggers deploy" do
|
|
20
|
+
provider = double('provider')
|
|
21
|
+
expect(DPL::Provider).to receive(:new).and_return(provider)
|
|
22
|
+
expect(provider).to receive(:deploy)
|
|
23
|
+
|
|
24
|
+
described_class.run("--provider=foo")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
example "error handling" do
|
|
28
|
+
expect($stderr).to receive(:puts).with('missing provider')
|
|
29
|
+
expect { described_class.run }.to raise_error(SystemExit)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
example "error handling in debug mode" do
|
|
33
|
+
expect { described_class.run("--debug") }.to raise_error(DPL::Error, 'missing provider')
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|