engineyard 1.3.10 → 1.3.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,47 +2,58 @@ require 'escape'
2
2
 
3
3
  module EY
4
4
  module Model
5
- class Deployment < ApiStruct.new(:id, :app, :created_at, :environment, :finished_at, :migration_command, :output, :ref, :successful)
6
- def self.started(environment, app, ref, migration_command)
7
- from_hash({
8
- :app => app,
9
- :environment => environment,
10
- :migration_command => migration_command,
11
- :ref => ref,
12
- :created_at => Time.now.utc,
5
+ class Deployment < ApiStruct.new(:id, :app, :created_at, :commit, :environment, :finished_at, :migrate_command, :output, :ref, :resolved_ref, :successful)
6
+ def self.started(environment, app, ref, migrate_command)
7
+ deployment = from_hash({
8
+ :app => app,
9
+ :environment => environment,
10
+ :migrate_command => migrate_command,
11
+ :ref => ref,
12
+ })
13
+ deployment.start
14
+ deployment
15
+ end
16
+
17
+ def start
18
+ post_to_api({
19
+ :migrate => !!migrate_command,
20
+ :migrate_command => migrate_command,
21
+ :output => output,
22
+ :ref => ref,
13
23
  })
14
24
  end
15
25
 
16
26
  def finished(successful, output)
17
27
  self.successful = successful
18
28
  self.output = output
19
- self.finished_at = Time.now.utc
20
- post_to_appcloud!
29
+ put_to_api({:successful => successful, :output => output})
21
30
  end
22
31
 
23
32
  private
24
33
 
25
- def post_to_appcloud!
26
- api.request(api_uri, :method => :post, :params => params)
27
- EY.ui.info "Deployment recorded in AppCloud"
34
+ def post_to_api(params)
35
+ update_with_response api.request(collection_uri, :method => :post, :params => {:deployment => params})
28
36
  end
29
37
 
30
- def params
31
- {:deployment => {
32
- :created_at => created_at,
33
- :finished_at => finished_at,
34
- :migrate => !!migration_command,
35
- :migrate_command => migration_command,
36
- :output => output,
37
- :ref => ref,
38
- :successful => successful,
39
- }}
38
+ def put_to_api(params)
39
+ update_with_response api.request(member_uri("/finished"), :method => :put, :params => {:deployment => params})
40
+ end
41
+
42
+ def update_with_response(response)
43
+ data = response['deployment']
44
+ data.each do |key,val|
45
+ self[key] = val if members.include?(key)
46
+ end
40
47
  end
41
48
 
42
- def api_uri
49
+ def collection_uri
43
50
  "/apps/#{app.id}/environments/#{environment.id}/deployments"
44
51
  end
45
52
 
53
+ def member_uri(path = nil)
54
+ "/apps/#{app.id}/environments/#{environment.id}/deployments/#{id}#{path}"
55
+ end
56
+
46
57
  def api
47
58
  app.api
48
59
  end
@@ -20,17 +20,21 @@ module EY
20
20
  private :adapter
21
21
 
22
22
  def deploy(app, ref, migration_command=nil, extra_configuration=nil, verbose=false)
23
+ successful, output = false, ""
23
24
  deployment = Deployment.started(environment, app, ref, migration_command)
24
25
 
25
26
  deploy_command = adapter(app, verbose).deploy do |args|
26
27
  args.config = extra_configuration if extra_configuration
27
28
  args.migrate = migration_command if migration_command
28
- args.ref = ref
29
+ args.ref = deployment.resolved_ref
29
30
  end
30
31
 
31
- successful, output = invoke_with_output(deploy_command)
32
- deployment.finished(successful, output)
33
- successful
32
+ successful = invoke(deploy_command) { |chunk| output << chunk }
33
+ ensure
34
+ if deployment
35
+ deployment.finished(successful, output)
36
+ EY.ui.info "#{successful ? 'Successful' : 'Failed'} deployment recorded in AppCloud"
37
+ end
34
38
  end
35
39
 
36
40
  def rollback(app, extra_configuration=nil, verbose=false)
@@ -67,32 +71,27 @@ module EY
67
71
 
68
72
  private
69
73
 
70
- def ssh(remote_command)
74
+ def ssh(remote_command, &block)
75
+ raise(ArgumentError, "Block required!") unless block_given?
71
76
  user = environment.username
72
- out = ""
73
- tee = lambda do |chunk|
74
- out << chunk
75
- $stdout << chunk
76
- end
77
-
78
77
  cmd = Escape.shell_command(%w[ssh -o StrictHostKeyChecking=no -q] << "#{user}@#{hostname}" << remote_command)
79
78
  EY.ui.debug(cmd)
80
79
  if ENV["NO_SSH"]
81
- [true, "NO_SSH is set."]
80
+ block.call("NO_SSH is set. No output.")
81
+ true
82
82
  else
83
- status = Open4.spawn(cmd, :out => tee, :err => tee, :quiet => true)
84
- [status.success?, out]
83
+ status = Open4.spawn(cmd, :out => block, :err => block, :quiet => true)
84
+ status.success?
85
85
  end
86
86
  end
87
87
 
88
- def invoke(action)
89
- invoke_with_output(action).first
90
- end
91
-
92
- def invoke_with_output(action)
88
+ def invoke(action, &block)
93
89
  action.call do |cmd|
94
90
  puts cmd if action.verbose
95
- ssh cmd
91
+ ssh cmd do |chunk|
92
+ $stdout << chunk
93
+ block.call(chunk) if block
94
+ end
96
95
  end
97
96
  end
98
97
 
@@ -1,3 +1,3 @@
1
1
  module EY
2
- VERSION = '1.3.10'
2
+ VERSION = '1.3.11'
3
3
  end
@@ -38,7 +38,7 @@ describe "ey deploy" do
38
38
 
39
39
  def verify_ran(scenario)
40
40
  @out.should match(/Beginning deploy for.*#{scenario[:application]}.*#{scenario[:environment]}/)
41
- @out.should match(/Deployment recorded in AppCloud/)
41
+ @out.should match(/deployment recorded in AppCloud/i)
42
42
  @ssh_commands.should have_command_like(/engineyard-serverside.*deploy.*--app #{scenario[:application]}/)
43
43
  end
44
44
 
@@ -200,27 +200,27 @@ describe "ey deploy" do
200
200
  context "without a configured default branch" do
201
201
  it "defaults to the checked-out local branch" do
202
202
  ey "deploy"
203
- @ssh_commands.last.should =~ /--ref current-branch/
203
+ @ssh_commands.last.should =~ /--ref resolved-current-branch/
204
204
  end
205
205
 
206
206
  it "deploys another branch if given" do
207
207
  ey "deploy --ref master"
208
- @ssh_commands.last.should =~ /--ref master/
208
+ @ssh_commands.last.should =~ /--ref resolved-master/
209
209
  end
210
210
 
211
211
  it "deploys a tag if given" do
212
212
  ey "deploy --ref v1"
213
- @ssh_commands.last.should =~ /--ref v1/
213
+ @ssh_commands.last.should =~ /--ref resolved-v1/
214
214
  end
215
215
 
216
216
  it "allows using --branch to specify a branch" do
217
217
  ey "deploy --branch master"
218
- @ssh_commands.last.should match(/--ref master/)
218
+ @ssh_commands.last.should match(/--ref resolved-master/)
219
219
  end
220
220
 
221
221
  it "allows using --tag to specify the tag" do
222
222
  ey "deploy --tag v1"
223
- @ssh_commands.last.should match(/--ref v1/)
223
+ @ssh_commands.last.should match(/--ref resolved-v1/)
224
224
  end
225
225
  end
226
226
 
@@ -250,7 +250,7 @@ describe "ey deploy" do
250
250
 
251
251
  it "deploys the default branch by default" do
252
252
  ey "deploy"
253
- @ssh_commands.last.should =~ /--ref master/
253
+ @ssh_commands.last.should =~ /--ref resolved-master/
254
254
  end
255
255
 
256
256
  it "complains about a non-default branch without --ignore-default_branch" do
@@ -260,7 +260,7 @@ describe "ey deploy" do
260
260
 
261
261
  it "deploys a non-default branch with --ignore-default-branch" do
262
262
  ey "deploy -r current-branch --ignore-default-branch"
263
- @ssh_commands.last.should =~ /--ref current-branch/
263
+ @ssh_commands.last.should =~ /--ref resolved-current-branch/
264
264
  end
265
265
  end
266
266
  end
@@ -327,7 +327,7 @@ describe "ey deploy" do
327
327
  it "allows you to specify an app when not in a directory" do
328
328
  ey "deploy --app rails232app --ref master"
329
329
  @ssh_commands.last.should match(/--app rails232app/)
330
- @ssh_commands.last.should match(/--ref master/)
330
+ @ssh_commands.last.should match(/--ref resolved-master/)
331
331
  end
332
332
 
333
333
  it "requires that you specify a ref when specifying the application" do
@@ -107,7 +107,11 @@ class FakeAwsm < Sinatra::Base
107
107
  end
108
108
 
109
109
  post "/api/v2/apps/:app_id/environments/:environment_id/deployments" do
110
- {"deployment" => params[:deployment].merge({"id" => 2, "commit" => 'a'*40})}.to_json
110
+ {"deployment" => params[:deployment].merge({"id" => 2, "commit" => 'a'*40, "resolved_ref" => "resolved-#{params[:deployment][:ref]}"})}.to_json
111
+ end
112
+
113
+ put "/api/v2/apps/:app_id/environments/:environment_id/deployments/:deployment_id/finished" do
114
+ {"deployment" => params[:deployment].merge({"id" => 2, "finished_at" => Time.now})}.to_json
111
115
  end
112
116
 
113
117
  post "/api/v2/authenticate" do
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 1
7
7
  - 3
8
- - 10
9
- version: 1.3.10
8
+ - 11
9
+ version: 1.3.11
10
10
  platform: ruby
11
11
  authors:
12
12
  - EY Cloud Team