dpl 2.0.0.alpha.2 → 2.0.0.alpha.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +34 -1
- data/Gemfile.lock +13 -8
- data/NOTES.md +1 -74
- data/README.md +464 -193
- data/lib/dpl/assets/convox/install +11 -0
- data/lib/dpl/assets/dpl/README.erb.md +4 -0
- data/lib/dpl/cli.rb +54 -18
- data/lib/dpl/ctx/test.rb +7 -3
- data/lib/dpl/helper/env.rb +67 -18
- data/lib/dpl/helper/wrap.rb +9 -0
- data/lib/dpl/provider.rb +11 -9
- data/lib/dpl/provider/dsl.rb +3 -1
- data/lib/dpl/provider/status.rb +6 -6
- data/lib/dpl/providers.rb +3 -1
- data/lib/dpl/providers/anynines.rb +5 -3
- data/lib/dpl/providers/azure_web_apps.rb +1 -1
- data/lib/dpl/providers/bintray.rb +2 -0
- data/lib/dpl/providers/bluemixcloudfoundry.rb +5 -3
- data/lib/dpl/providers/boxfuse.rb +1 -1
- data/lib/dpl/providers/cargo.rb +10 -1
- data/lib/dpl/providers/chef_supermarket.rb +3 -1
- data/lib/dpl/providers/cloud66.rb +2 -0
- data/lib/dpl/providers/cloudfiles.rb +2 -0
- data/lib/dpl/providers/cloudformation.rb +278 -0
- data/lib/dpl/providers/cloudfoundry.rb +6 -4
- data/lib/dpl/providers/codedeploy.rb +5 -5
- data/lib/dpl/providers/convox.rb +121 -0
- data/lib/dpl/providers/datica.rb +1 -1
- data/lib/dpl/providers/engineyard.rb +2 -0
- data/lib/dpl/providers/gae.rb +6 -7
- data/lib/dpl/providers/gcs.rb +5 -3
- data/lib/dpl/providers/gleis.rb +70 -0
- data/lib/dpl/providers/hackage.rb +2 -0
- data/lib/dpl/providers/hephy.rb +3 -1
- data/lib/dpl/providers/heroku.rb +4 -8
- data/lib/dpl/providers/heroku/api.rb +4 -2
- data/lib/dpl/providers/heroku/git.rb +3 -1
- data/lib/dpl/providers/lambda.rb +4 -4
- data/lib/dpl/providers/launchpad.rb +3 -1
- data/lib/dpl/providers/netlify.rb +2 -0
- data/lib/dpl/providers/npm.rb +2 -0
- data/lib/dpl/providers/openshift.rb +2 -0
- data/lib/dpl/providers/opsworks.rb +1 -1
- data/lib/dpl/providers/packagecloud.rb +2 -0
- data/lib/dpl/providers/pages.rb +4 -7
- data/lib/dpl/providers/pages/api.rb +16 -12
- data/lib/dpl/providers/pages/git.rb +16 -12
- data/lib/dpl/providers/puppetforge.rb +2 -0
- data/lib/dpl/providers/pypi.rb +2 -0
- data/lib/dpl/providers/releases.rb +8 -6
- data/lib/dpl/providers/rubygems.rb +3 -1
- data/lib/dpl/providers/s3.rb +7 -7
- data/lib/dpl/providers/scalingo.rb +2 -0
- data/lib/dpl/providers/testfairy.rb +2 -0
- data/lib/dpl/providers/transifex.rb +2 -0
- data/lib/dpl/version.rb +1 -1
- metadata +7 -3
- data/lib/dpl/providers/atlas.rb +0 -49
@@ -22,10 +22,12 @@ module Dpl
|
|
22
22
|
gem 'net-telnet', '~> 0.1.0' if ruby_pre?('2.3')
|
23
23
|
gem 'rack'
|
24
24
|
|
25
|
+
env :chef
|
26
|
+
|
25
27
|
opt '--user_id ID', 'Chef Supermarket user name', required: true
|
26
|
-
opt '--client_key KEY', 'Client API key file name', required: true
|
27
28
|
opt '--name NAME', 'Cookbook name', note: 'defaults to the name given in metadata.json or metadata.rb', alias: :cookbook_name, deprecated: :cookbook_name
|
28
29
|
opt '--category CAT', 'Cookbook category in Supermarket', required: true, see: 'https://docs.getchef.com/knife_cookbook_site.html#id12', alias: :cookbook_category, deprecated: :cookbook_category
|
30
|
+
opt '--client_key KEY', 'Client API key file name', default: 'client.pem'
|
29
31
|
opt '--dir DIR', 'Directory containing the cookbook', default: '.'
|
30
32
|
|
31
33
|
URL = "https://supermarket.chef.io/api/v1/cookbooks"
|
@@ -13,6 +13,8 @@ module Dpl
|
|
13
13
|
gem 'fog-core', '= 2.1.0', require: 'fog/core'
|
14
14
|
gem 'fog-rackspace', '~> 0.1.6', require: 'fog/rackspace'
|
15
15
|
|
16
|
+
env :cloudfiles
|
17
|
+
|
16
18
|
opt '--username USER', 'Rackspace username', required: true
|
17
19
|
opt '--api_key KEY', 'Rackspace API key', required: true, secret: true
|
18
20
|
opt '--region REGION', 'Cloudfiles region', required: true, enum: %w(ord dfw syd iad hkg)
|
@@ -0,0 +1,278 @@
|
|
1
|
+
module Dpl
|
2
|
+
module Providers
|
3
|
+
class Cloudformation < Provider
|
4
|
+
status :dev
|
5
|
+
|
6
|
+
full_name 'AWS CloudFormation'
|
7
|
+
|
8
|
+
description sq(<<-str)
|
9
|
+
tbd
|
10
|
+
str
|
11
|
+
|
12
|
+
gem 'aws-sdk-cloudformation', '~> 1.0'
|
13
|
+
|
14
|
+
env :aws, :cloudformation
|
15
|
+
config '~/.aws/credentials', prefix: 'aws'
|
16
|
+
|
17
|
+
opt '--access_key_id ID', 'AWS Access Key ID', required: true, secret: true
|
18
|
+
opt '--secret_access_key KEY', 'AWS Secret Key', required: true, secret: true
|
19
|
+
opt '--region REGION', 'AWS Region to deploy to', default: 'us-east-1'
|
20
|
+
opt '--template STR', 'CloudFormation template file', required: true, note: 'can be either a local path or an S3 URL'
|
21
|
+
opt '--stack_name NAME', 'CloudFormation Stack Name.', required: true
|
22
|
+
opt '--stack_name_prefix STR', 'CloudFormation Stack Name Prefix.'
|
23
|
+
opt '--promote', 'Deploy changes', default: true, note: 'otherwise a change set is created'
|
24
|
+
opt '--role_arn ARN', 'AWS Role ARN'
|
25
|
+
opt '--sts_assume_role ARN', 'AWS Role ARN for cross account deployments (assumed by travis using given AWS credentials).'
|
26
|
+
opt '--capabilities STR', 'CloudFormation allowed capabilities', type: :array, enum: %w(CAPABILITY_IAM CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND), sep: ',', see: 'https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateStack.html'
|
27
|
+
opt '--wait', 'Wait for CloutFormation to finish the stack creation and update', default: true
|
28
|
+
opt '--wait_timeout SEC', 'How many seconds to wait for stack creation and update.', type: :integer, default: 3600
|
29
|
+
opt '--create_timeout SEC', 'How many seconds to wait before the stack status becomes CREATE_FAILED', type: :integer, default: 3600, note: 'valid only when creating a stack'
|
30
|
+
# if passing a session_token is not recommended in CI/CD why do we add it to dpl?
|
31
|
+
opt '--session_token STR', 'AWS Session Access Token if using STS assume role', note: 'Not recommended on CI/CD'
|
32
|
+
opt '--parameters STR', 'key=value pairs or ENV var names', type: :array, sep: ',', eg: 'one=1 or ENV_VAR_TWO'
|
33
|
+
opt '--output_file PATH', 'Path to output file to store CloudFormation outputs to'
|
34
|
+
|
35
|
+
msgs login: 'Using Access Key: %{access_key_id}',
|
36
|
+
create_stack: 'Creating stack ...',
|
37
|
+
promote_stack: 'Promoting stack ...',
|
38
|
+
create_change_set: 'Creating change set ...',
|
39
|
+
stack_up_to_date: 'Stack already up to date.',
|
40
|
+
delete_change_set: 'No changes in stack. Removing changeset.',
|
41
|
+
done: 'Done.',
|
42
|
+
missing_template: 'File does not exist: %{template}',
|
43
|
+
invalid_creds: 'Invalid credentials'
|
44
|
+
|
45
|
+
strs change_set_name: 'travis-ci-build-%{build_number}-%{now}',
|
46
|
+
change_set_desc: 'Changeset created by Travis CI job for build #%{build_number} (%{git_sha})'
|
47
|
+
|
48
|
+
def login
|
49
|
+
info :login
|
50
|
+
end
|
51
|
+
|
52
|
+
def deploy
|
53
|
+
stack_exists? ? update : create
|
54
|
+
store_events if output_file?
|
55
|
+
rescue Aws::CloudFormation::Errors::InvalidAccessKeyId
|
56
|
+
error :invalid_creds
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def update
|
62
|
+
promote? ? promote : create_change_set(:update)
|
63
|
+
rescue Aws::CloudFormation::Errors::ValidationError => e
|
64
|
+
raise e unless e.message.start_with?('No updates are to be performed')
|
65
|
+
info :stack_up_to_date
|
66
|
+
end
|
67
|
+
|
68
|
+
def promote
|
69
|
+
info :promote_stack
|
70
|
+
client.update_stack(common_params)
|
71
|
+
stream_events(stack_name, :stack_update_complete) if wait?
|
72
|
+
info :done
|
73
|
+
end
|
74
|
+
|
75
|
+
def create
|
76
|
+
promote? ? create_stack : create_change_set(:create)
|
77
|
+
end
|
78
|
+
|
79
|
+
def create_stack
|
80
|
+
info :create_stack
|
81
|
+
params = { timeout_in_minutes: create_timeout, on_failure: 'ROLLBACK' }
|
82
|
+
client.create_stack(common_params.merge(params))
|
83
|
+
stream_events(stack_name, :stack_create_complete) if wait?
|
84
|
+
info :done
|
85
|
+
end
|
86
|
+
|
87
|
+
def create_change_set(type)
|
88
|
+
info :create_change_set
|
89
|
+
set = client.create_change_set(common_params.merge(change_set_params(type)))
|
90
|
+
wait_for(:change_set_create_complete, change_set_name: set.id) if wait? && !test?
|
91
|
+
info :done
|
92
|
+
rescue Aws::Waiters::Errors::FailureStateError => e
|
93
|
+
raise e unless change_set_contains_changes?(set)
|
94
|
+
info :delete_change_set
|
95
|
+
client.delete_change_set(change_set_name: set.id)
|
96
|
+
end
|
97
|
+
|
98
|
+
def change_set_params(type)
|
99
|
+
{
|
100
|
+
change_set_type: type.to_s.upcase,
|
101
|
+
change_set_name: interpolate(str(:change_set_name)),
|
102
|
+
description: interpolate(str(:change_set_desc))
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
def change_set_contains_changes?(change_set)
|
107
|
+
data = client.describe_change_set(change_set_name: change_set.id)
|
108
|
+
data.status_reason.start_with?(%(The submitted information didn't contain changes))
|
109
|
+
end
|
110
|
+
|
111
|
+
def stack_exists?
|
112
|
+
stack = last_stack
|
113
|
+
stack && stack.stack_status != 'REVIEW_IN_PROGRESS'
|
114
|
+
rescue Aws::CloudFormation::Errors::ValidationError => e
|
115
|
+
raise e unless e.message.include?('does not exist')
|
116
|
+
false
|
117
|
+
end
|
118
|
+
|
119
|
+
def stream_events(stack_name, condition)
|
120
|
+
stream = EventStream.new(client, stack_name, method(:info))
|
121
|
+
wait_for(condition, stack_name: stack_name) unless test? # hmm.
|
122
|
+
ensure
|
123
|
+
stream.stop unless stream.nil?
|
124
|
+
end
|
125
|
+
|
126
|
+
def wait_for(cond, params)
|
127
|
+
started_at = Time.now
|
128
|
+
timeout = lambda { |*| throw :failure if Time.now - started_at > wait_timeout }
|
129
|
+
# params = params.merge(max_attempts: nil, delay: 5, before_wait: timeout)
|
130
|
+
client.wait_until(cond, params) { |w| w.before_wait(&timeout) }
|
131
|
+
end
|
132
|
+
|
133
|
+
def store_events
|
134
|
+
logs = last_stack.outputs || {}
|
135
|
+
logs = logs.map { |log| "#{log[:output_key]}=#{log[:output_value]}" }
|
136
|
+
File.write(output_file, logs.join("\n"))
|
137
|
+
end
|
138
|
+
|
139
|
+
def last_stack
|
140
|
+
client.describe_stacks(stack_name: stack_name)[:stacks].first
|
141
|
+
end
|
142
|
+
|
143
|
+
def common_params
|
144
|
+
params = {
|
145
|
+
stack_name: stack_name,
|
146
|
+
role_arn: role_arn,
|
147
|
+
capabilities: capabilities,
|
148
|
+
parameters: parameters
|
149
|
+
}
|
150
|
+
params.merge!(template_param)
|
151
|
+
@common_params ||= compact(params)
|
152
|
+
end
|
153
|
+
|
154
|
+
def parameters
|
155
|
+
@parameters ||= Array(super).map do |str|
|
156
|
+
key, value = str.split('=', 2)
|
157
|
+
{ parameter_key: key, parameter_value: value || ENV[key] }
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def create_timeout
|
162
|
+
super / 60
|
163
|
+
end
|
164
|
+
|
165
|
+
def stack_name
|
166
|
+
@stack_name ||= "#{stack_name_prefix}#{super}"
|
167
|
+
end
|
168
|
+
|
169
|
+
def template_param
|
170
|
+
str = template
|
171
|
+
return { template_url: str } if url?(str)
|
172
|
+
return { template_body: read(str) } if file?(str)
|
173
|
+
error(:missing_template)
|
174
|
+
end
|
175
|
+
|
176
|
+
def client
|
177
|
+
@client ||= Aws::CloudFormation::Client.new(client_options)
|
178
|
+
end
|
179
|
+
|
180
|
+
def client_options
|
181
|
+
params = { region: region, credentials: credentials }
|
182
|
+
params = params.merge(credentials: assume_role(params)) if sts_assume_role?
|
183
|
+
params
|
184
|
+
end
|
185
|
+
|
186
|
+
def credentials
|
187
|
+
Aws::Credentials.new(access_key_id, secret_access_key, session_token)
|
188
|
+
end
|
189
|
+
|
190
|
+
def assume_role(params)
|
191
|
+
assumed_role = Aws::STS::Client.new(params).assume_role(
|
192
|
+
role_arn: sts_assume_role,
|
193
|
+
role_session_name: "travis-build-#{build_number}"
|
194
|
+
)
|
195
|
+
Aws::Credentials.new(
|
196
|
+
assumed_role.credentials.access_key_id,
|
197
|
+
assumed_role.credentials.secret_access_key,
|
198
|
+
assumed_role.credentials.session_token
|
199
|
+
)
|
200
|
+
end
|
201
|
+
|
202
|
+
def now
|
203
|
+
Time.now.strftime('%Y-%m-%dT%H:%M:%S')
|
204
|
+
end
|
205
|
+
|
206
|
+
def url?(str)
|
207
|
+
str =~ %r(^https?://)
|
208
|
+
end
|
209
|
+
|
210
|
+
class EventStream < Struct.new(:client, :stack_name, :handler)
|
211
|
+
attr_reader :thread
|
212
|
+
|
213
|
+
def initialize(*)
|
214
|
+
super
|
215
|
+
@event = describe_stack_events.stack_events.first
|
216
|
+
@thread = Thread.new(&method(:process))
|
217
|
+
end
|
218
|
+
|
219
|
+
def stop
|
220
|
+
mutex.synchronize { @stop = true }
|
221
|
+
thread.join
|
222
|
+
end
|
223
|
+
|
224
|
+
private
|
225
|
+
|
226
|
+
def process
|
227
|
+
until mutex.synchronize { @stop }
|
228
|
+
@event, events = events_since(@event)
|
229
|
+
events.each { |e| handler.call(format_event(e)) }
|
230
|
+
sleep 5 unless ENV['ENV'] == 'test'
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
# source: https://github.com/rvedotrc/cfn-events/blob/master/lib/cfn-events/runner.rb
|
235
|
+
def events_since(event)
|
236
|
+
described_stack = describe_stack_events
|
237
|
+
stack_events = described_stack.stack_events
|
238
|
+
return [event, []] if stack_events.first.event_id == event.event_id
|
239
|
+
|
240
|
+
events = []
|
241
|
+
described_stack.each_page do |page|
|
242
|
+
|
243
|
+
|
244
|
+
if (oldest_new = page.stack_events.index { |e| e.event_id == event.event_id })
|
245
|
+
events.concat(page.stack_events[0..oldest_new - 1])
|
246
|
+
return [events.first, events.reverse]
|
247
|
+
end
|
248
|
+
events.concat(page.stack_events)
|
249
|
+
end
|
250
|
+
|
251
|
+
warn %(Last-seen stack event is no longer returned by AWS. Please raise this as a provider's bug.)
|
252
|
+
[events.first, events.reverse]
|
253
|
+
end
|
254
|
+
|
255
|
+
def describe_stack_events
|
256
|
+
client.describe_stack_events(stack_name: stack_name)
|
257
|
+
end
|
258
|
+
|
259
|
+
def mutex
|
260
|
+
@mutex ||= Mutex.new
|
261
|
+
end
|
262
|
+
|
263
|
+
EVENT_KEYS = %i(timestamp resource_type resource_status logical_resource_id
|
264
|
+
physical_resource_id resource_status_reason)
|
265
|
+
|
266
|
+
def format_event(event)
|
267
|
+
parts = EVENT_KEYS.map { |key| event.send(key) }
|
268
|
+
parts[0] = format_timestamp(parts[0])
|
269
|
+
parts.join(' ')
|
270
|
+
end
|
271
|
+
|
272
|
+
def format_timestamp(timestamp)
|
273
|
+
timestamp.utc.strftime('%Y-%m-%dT%H:%M:%SZ')
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
@@ -9,13 +9,15 @@ module Dpl
|
|
9
9
|
tbd
|
10
10
|
str
|
11
11
|
|
12
|
+
env :cloudfoundry
|
13
|
+
|
12
14
|
opt '--username USER', 'Cloud Foundry username', required: true
|
13
15
|
opt '--password PASS', 'Cloud Foundry password', required: true, secret: true
|
14
|
-
opt '--organization ORG', 'Cloud Foundry
|
15
|
-
opt '--space SPACE', 'Cloud Foundry
|
16
|
-
opt '--api URL', 'Cloud Foundry api URL',
|
16
|
+
opt '--organization ORG', 'Cloud Foundry organization', required: true
|
17
|
+
opt '--space SPACE', 'Cloud Foundry space', required: true
|
18
|
+
opt '--api URL', 'Cloud Foundry api URL', default: 'https://api.run.pivotal.io'
|
17
19
|
opt '--app_name APP', 'Application name'
|
18
|
-
opt '--buildpack PACK', '
|
20
|
+
opt '--buildpack PACK', 'Buildpack name or Git URL'
|
19
21
|
opt '--manifest FILE', 'Path to the manifest'
|
20
22
|
opt '--skip_ssl_validation', 'Skip SSL validation'
|
21
23
|
opt '--v3', 'Use the v3 API version to push the application'
|
@@ -14,7 +14,7 @@ module Dpl
|
|
14
14
|
gem 'aws-sdk-codedeploy', '~> 1.0'
|
15
15
|
gem 'aws-sdk-s3', '~> 1.0'
|
16
16
|
|
17
|
-
env :aws
|
17
|
+
env :aws, :codedeploy
|
18
18
|
config '~/.aws/credentials', '~/.aws/config', prefix: 'aws'
|
19
19
|
|
20
20
|
opt '--access_key_id ID', 'AWS access key', required: true, secret: true
|
@@ -28,10 +28,10 @@ module Dpl
|
|
28
28
|
opt '--region REGION', 'AWS availability zone', default: 'us-east-1'
|
29
29
|
opt '--file_exists_behavior STR', 'How to handle files that already exist in a deployment target location', enum: %w(disallow overwrite retain), default: 'disallow'
|
30
30
|
opt '--wait_until_deployed', 'Wait until the deployment has finished'
|
31
|
-
opt '--bundle_type TYPE'
|
32
|
-
opt '--
|
33
|
-
opt '--
|
34
|
-
opt '--
|
31
|
+
opt '--bundle_type TYPE', 'Bundle type of the revision'
|
32
|
+
opt '--key KEY', 'S3 bucket key of the revision'
|
33
|
+
opt '--description DESCR', 'Description of the revision'
|
34
|
+
opt '--endpoint ENDPOINT', 'S3 endpoint url'
|
35
35
|
|
36
36
|
msgs login: 'Using Access Key: %{access_key_id}',
|
37
37
|
deploy_triggered: 'Deployment triggered: %s',
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module Dpl
|
2
|
+
module Providers
|
3
|
+
class Convox < Provider
|
4
|
+
status :dev
|
5
|
+
|
6
|
+
description sq(<<-str)
|
7
|
+
tbd
|
8
|
+
str
|
9
|
+
|
10
|
+
gem 'json'
|
11
|
+
|
12
|
+
env :convox
|
13
|
+
|
14
|
+
# needs descriptions
|
15
|
+
opt '--host HOST', default: 'console.convox.com'
|
16
|
+
opt '--app APP', required: true
|
17
|
+
opt '--rack RACK', required: true
|
18
|
+
opt '--password PASS', required: true
|
19
|
+
opt '--install_url URL', default: 'https://convox.com/cli/linux/convox'
|
20
|
+
opt '--update_cli'
|
21
|
+
opt '--create'
|
22
|
+
opt '--promote', default: true
|
23
|
+
opt '--env VARS', type: :array, sep: ','
|
24
|
+
opt '--env_file FILE'
|
25
|
+
opt '--description STR'
|
26
|
+
opt '--generation NUM', type: :int, default: '2'
|
27
|
+
|
28
|
+
# if app and rack are exported to the env, do they need to be passed to these commands?
|
29
|
+
cmds login: 'convox version --rack %{rack}',
|
30
|
+
validate: 'convox apps info --rack %{rack} --app %{app}',
|
31
|
+
create: 'convox apps create %{app} --generation %{generation} --rack %{rack} --wait',
|
32
|
+
update: 'convox update',
|
33
|
+
set_env: 'convox env set %{env} --rack %{rack} --app %{app} --replace',
|
34
|
+
build: 'convox build --rack %{rack} --app %{app} --id --description %{escaped_description}',
|
35
|
+
deploy: 'convox deploy --rack %{rack} --app %{app} --wait --id --description %{escaped_description}'
|
36
|
+
|
37
|
+
msgs create: 'Application %{app} does not exist on rack %{rack}. Creating it ...',
|
38
|
+
missing: 'Application %{app} does not exist on rack %{rack}.',
|
39
|
+
env_file: 'The given env_file does not exist.',
|
40
|
+
deploy: 'Building and promoting application ...',
|
41
|
+
build: 'Building application ...'
|
42
|
+
|
43
|
+
errs login: 'Login failed.'
|
44
|
+
|
45
|
+
def install
|
46
|
+
script :install
|
47
|
+
shell :update if update_cli?
|
48
|
+
export
|
49
|
+
end
|
50
|
+
|
51
|
+
def login
|
52
|
+
shell :login
|
53
|
+
end
|
54
|
+
|
55
|
+
def validate
|
56
|
+
shell :validate, assert: false and return
|
57
|
+
error :missing unless create?
|
58
|
+
shell :create
|
59
|
+
end
|
60
|
+
|
61
|
+
def deploy
|
62
|
+
shell :set_env, echo: false unless env.empty?
|
63
|
+
shell promote ? :deploy : :build, echo: false
|
64
|
+
end
|
65
|
+
|
66
|
+
# not sure about this api. i like that there is an api for people to include
|
67
|
+
# env vars from the current build env, but maybe it would be better to expose
|
68
|
+
# FOO=$FOO? is mapping a bare env key to a key/value pair a concept in convox?
|
69
|
+
#
|
70
|
+
# def env
|
71
|
+
# env = env_file.concat(super || []) # TODO Cl should return an empty array, shouldn't it?
|
72
|
+
# env = env.map { |str| str.include?('=') ? str : "#{str}=#{ENV[str]}" }
|
73
|
+
# env.map { |str| escape(str) }.join(' ')
|
74
|
+
# end
|
75
|
+
|
76
|
+
# here's an alternative implementation that would expose FOO=$FOO:
|
77
|
+
gem 'sh_vars', '~> 1.0.2'
|
78
|
+
|
79
|
+
def env
|
80
|
+
env = env_file.concat(super || [])
|
81
|
+
env = env.map { |str| ShVars.parse(str).to_h }.inject(&:merge) || {}
|
82
|
+
env.map { |key, value| "#{key}=#{value.inspect}" }.join(' ')
|
83
|
+
end
|
84
|
+
|
85
|
+
def env_file
|
86
|
+
return [] unless env_file?
|
87
|
+
error :env_file unless file?(super)
|
88
|
+
lines = read(super).split("\n").map(&:strip)
|
89
|
+
lines.reject(&:empty?)
|
90
|
+
end
|
91
|
+
|
92
|
+
def description
|
93
|
+
description? ? super : JSON.dump(
|
94
|
+
repo_slug: repo_slug,
|
95
|
+
git_commit_sha: git_sha,
|
96
|
+
git_commit_message: git_commit_msg,
|
97
|
+
git_commit_author: git_author_name,
|
98
|
+
git_tag: git_tag,
|
99
|
+
branch: git_branch,
|
100
|
+
travis_build_id: ENV['TRAVIS_BUILD_ID'],
|
101
|
+
travis_build_number: ENV['TRAVIS_BUILD_NUMBER'],
|
102
|
+
pull_request: ENV['TRAVIS_PULL_REQUEST']
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
def export
|
107
|
+
env_vars.each { |key, value| ENV[key.to_s] = value.to_s }
|
108
|
+
end
|
109
|
+
|
110
|
+
def env_vars
|
111
|
+
{
|
112
|
+
CONVOX_HOST: host,
|
113
|
+
CONVOX_PASSWORD: password,
|
114
|
+
CONVOX_APP: app,
|
115
|
+
CONVOX_RACK: rack,
|
116
|
+
CONVOX_CLI: 'convox'
|
117
|
+
}
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|