cf-deploy 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +42 -28
- data/lib/cf/deploy.rb +15 -12
- data/lib/cf/deploy/blue_green.rb +35 -22
- data/lib/cf/deploy/commands.rb +12 -9
- data/lib/cf/deploy/config.rb +6 -6
- data/lib/cf/deploy/env_config.rb +30 -16
- data/lib/cf/deploy/version.rb +1 -1
- data/spec/blue_green_task_spec.rb +9 -10
- data/spec/flip_task_spec.rb +18 -9
- data/spec/rake_tasks_spec.rb +10 -3
- data/spec/stop_idle_task_spec.rb +38 -0
- metadata +30 -11
- checksums.yaml +0 -7
data/README.md
CHANGED
@@ -42,8 +42,8 @@ Things start to get more exciting when you define your environments in your
|
|
42
42
|
require 'cf-deploy'
|
43
43
|
|
44
44
|
CF::Deploy.rake_tasks! do
|
45
|
-
environment :
|
46
|
-
environment :
|
45
|
+
environment staging: 'assets:precompile'
|
46
|
+
environment production: [:clean, 'assets:precompile']
|
47
47
|
end
|
48
48
|
```
|
49
49
|
|
@@ -57,21 +57,21 @@ environment block like so:
|
|
57
57
|
require 'cf-deploy'
|
58
58
|
|
59
59
|
CF::Deploy.rake_tasks! do
|
60
|
-
environment :
|
60
|
+
environment staging: 'assets:precompile' do
|
61
61
|
route 'example.com', 'staging'
|
62
62
|
end
|
63
63
|
|
64
|
-
environment :
|
64
|
+
environment production: [:clean, 'assets:precompile'] do
|
65
65
|
route 'example.com'
|
66
|
+
route 'example.com', 'www'
|
67
|
+
route 'example.com', 'www-origin'
|
66
68
|
route 'example.com', 'admin'
|
67
|
-
flip_route 'yourwebsite', 'www'
|
68
|
-
flip_route 'yourwebsite', 'www-origin'
|
69
69
|
end
|
70
70
|
end
|
71
71
|
```
|
72
72
|
|
73
|
-
|
74
|
-
will be mapped to all applications in the environment's manifest.
|
73
|
+
As soon as an environment with routes is pushed successfully each of it's routes
|
74
|
+
will be mapped to all the applications defined in the environment's manifest.
|
75
75
|
|
76
76
|
And then things get super interesting when you start talking blue/green.
|
77
77
|
|
@@ -82,36 +82,41 @@ app, test it on a private URL and then direct your traffic to the new version
|
|
82
82
|
when you are ready.
|
83
83
|
|
84
84
|
You have two applications for one environment, say production. One version is
|
85
|
-
called green, the other is blue. The first time you deploy your
|
86
|
-
|
87
|
-
color that doesn't have your production domain pointed at it.
|
88
|
-
a private URL and then when you're happy you flip your domain to
|
89
|
-
If something then goes wrong you can then flip your domain back
|
90
|
-
working version.
|
85
|
+
called green, the other is blue. The first time you deploy your environment
|
86
|
+
either green or blue can be deployed. Thereafter, any changes you want to deploy
|
87
|
+
you deploy to the color that doesn't have your production domain pointed at it.
|
88
|
+
You test it on a private URL and then when you're happy you flip your domain to
|
89
|
+
point at that. If something then goes wrong you can then flip your domain back
|
90
|
+
to the last working version.
|
91
91
|
|
92
92
|
This gem provides rake tasks for you to deploy using this methodology as well
|
93
93
|
as the standard single app deployment process on a CloudFoundry provider.
|
94
94
|
|
95
|
-
|
96
|
-
|
97
|
-
|
95
|
+
### An example of blue/green
|
96
|
+
|
97
|
+
Examples always help and this example is probably the most common use case. You
|
98
|
+
might have a straight forward deployment for staging but use the blue/green
|
99
|
+
strategy for production. Here is what your Rakefile might look like:
|
98
100
|
|
99
101
|
``` ruby
|
100
102
|
require 'cf-deploy'
|
101
103
|
|
102
104
|
CF::Deploy.rake_tasks! do
|
103
|
-
environment :
|
105
|
+
environment staging: 'assets:precompile'
|
104
106
|
|
105
|
-
environment :
|
106
|
-
route 'example-app.io'
|
107
|
-
|
108
|
-
|
107
|
+
environment production: 'assets:precompile' do
|
108
|
+
route 'example-app.io', flip: true
|
109
|
+
route 'example-app.io', 'www', flip: true
|
110
|
+
route 'example-app.io', 'www-origin', flip: true
|
109
111
|
end
|
110
112
|
end
|
111
113
|
```
|
112
114
|
|
113
|
-
You should also have
|
114
|
-
|
115
|
+
You should also have three manifests defined:
|
116
|
+
|
117
|
+
- `manifests/staging.yml`
|
118
|
+
- `manifests/production_blue.yml`
|
119
|
+
- `manifests/production_green.yml`
|
115
120
|
|
116
121
|
When you run `cf:deploy:production` for the first time (assuming neither
|
117
122
|
`production_blue.yml` or `production_green.yml` are deployed) your blue app will
|
@@ -134,7 +139,7 @@ the [CloudFoundry CLI][cli] repo on github.
|
|
134
139
|
You then need to install this gem in your project's `Gemfile`:
|
135
140
|
|
136
141
|
``` ruby
|
137
|
-
gem 'cf-deploy', '0.1.
|
142
|
+
gem 'cf-deploy', '0.1.1'
|
138
143
|
```
|
139
144
|
|
140
145
|
### Defining CloudFoundry details in your Rakefile
|
@@ -152,10 +157,10 @@ CF::Deploy.rake_tasks! do
|
|
152
157
|
organisation 'Made'
|
153
158
|
space 'development'
|
154
159
|
|
155
|
-
environment :
|
160
|
+
environment staging: 'assets:precompile'
|
156
161
|
|
157
|
-
environment :
|
158
|
-
|
162
|
+
environment production: 'assets:precompile' do
|
163
|
+
route 'yourwebsite.com', 'www', flip: true
|
159
164
|
end
|
160
165
|
end
|
161
166
|
```
|
@@ -239,6 +244,15 @@ This will go ahead and map routes to whatever color the routes aren't mapped to
|
|
239
244
|
and then unmap the other color. At this point your new production will be
|
240
245
|
deployed and live.
|
241
246
|
|
247
|
+
### Turn off idle app
|
248
|
+
|
249
|
+
Once your new production has been flipped you may want to turn off your idle
|
250
|
+
application. There is a task for this too:
|
251
|
+
|
252
|
+
```
|
253
|
+
bundle exec rake cf:deploy:production:stop_idle
|
254
|
+
```
|
255
|
+
|
242
256
|
## Credits
|
243
257
|
|
244
258
|
[![made](https://s3-eu-west-1.amazonaws.com/made-assets/googleapps/google-apps.png)][made]
|
data/lib/cf/deploy.rb
CHANGED
@@ -9,7 +9,7 @@ module CF
|
|
9
9
|
class Deploy
|
10
10
|
class << self
|
11
11
|
def rake_tasks!(&block)
|
12
|
-
new(:
|
12
|
+
new(config: Config.new(&block), commands: Commands.new).rake_tasks!
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -26,7 +26,7 @@ module CF
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def deploy_tasks
|
29
|
-
config[:environments].map { |env|
|
29
|
+
config[:environments].map { |env| define_deploy_tasks(env) }
|
30
30
|
end
|
31
31
|
|
32
32
|
def define_login_task
|
@@ -37,23 +37,26 @@ module CF
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
40
|
+
def define_deploy_tasks(env)
|
41
41
|
BlueGreen.new(env, config_task) if env[:deployments].size > 1
|
42
42
|
|
43
43
|
env[:deployments].each do |deployment|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
44
|
+
define_deploy_task(env, deployment)
|
45
|
+
end
|
46
|
+
end
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
48
|
+
def define_deploy_task(env, deployment)
|
49
|
+
Rake::Task.define_task(deployment[:task_name] => env[:deps]) do
|
50
|
+
unless cf.push(deployment[:manifest])
|
51
|
+
raise "Failed to deploy #{deployment}"
|
52
|
+
end
|
53
|
+
|
54
|
+
env[:routes].reject { |r| r[:flip] == true }.each do |route|
|
55
|
+
deployment[:app_names].each do |app_name|
|
56
|
+
cf.map_route(route, app_name)
|
53
57
|
end
|
54
58
|
end
|
55
59
|
end
|
56
60
|
end
|
57
|
-
|
58
61
|
end
|
59
62
|
end
|
data/lib/cf/deploy/blue_green.rb
CHANGED
@@ -3,7 +3,6 @@ require 'yaml'
|
|
3
3
|
module CF
|
4
4
|
class Deploy
|
5
5
|
class BlueGreen
|
6
|
-
|
7
6
|
attr_accessor :env, :config_task, :config, :cf
|
8
7
|
|
9
8
|
def initialize(env, config_task)
|
@@ -12,29 +11,36 @@ module CF
|
|
12
11
|
@config = config_task[:config]
|
13
12
|
@cf = config_task[:commands]
|
14
13
|
|
14
|
+
define_deployment_task
|
15
|
+
define_flip_task
|
16
|
+
define_stop_idle_task
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def define_deployment_task
|
15
22
|
Rake::Task.define_task(env[:task_name] => env[:deps]) do
|
16
|
-
task_name = EnvConfig.task_name("#{env[:name]}_#{
|
23
|
+
task_name = EnvConfig.task_name("#{env[:name]}_#{idle_color(env)}")
|
17
24
|
Rake::Task[task_name].invoke
|
18
25
|
end
|
26
|
+
end
|
19
27
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
next_app_in_production = app_name_from_color(next_production_colour(env))
|
28
|
+
def define_flip_task
|
29
|
+
Rake::Task.define_task("#{env[:task_name]}:flip" => 'cf:login') do
|
30
|
+
live_app_name = app_name_from_color(live_color(env))
|
31
|
+
idle_app_name = app_name_from_color(idle_color(env))
|
25
32
|
|
26
|
-
env
|
27
|
-
cf.map_route(route,
|
28
|
-
cf.unmap_route(route,
|
33
|
+
flip_routes(env).each do |route|
|
34
|
+
cf.map_route(route, idle_app_name)
|
35
|
+
cf.unmap_route(route, live_app_name)
|
29
36
|
end
|
30
37
|
end
|
31
38
|
end
|
32
39
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
cf.login(config)
|
40
|
+
def define_stop_idle_task
|
41
|
+
Rake::Task.define_task("#{env[:task_name]}:stop_idle" => 'cf:login') do
|
42
|
+
idle_app_name = app_name_from_color(idle_color(env))
|
43
|
+
cf.stop(idle_app_name)
|
38
44
|
end
|
39
45
|
end
|
40
46
|
|
@@ -42,22 +48,29 @@ module CF
|
|
42
48
|
env.app_name_for_colour(colour)
|
43
49
|
end
|
44
50
|
|
51
|
+
def flip_routes(env)
|
52
|
+
env[:routes].select { |r| r[:flip] == true }
|
53
|
+
end
|
54
|
+
|
45
55
|
def match_flip_route_grep(env)
|
46
|
-
if env
|
56
|
+
if flip_routes(env).empty?
|
47
57
|
raise 'Blue/green deploys require at least one flip_route'
|
48
58
|
end
|
49
59
|
|
50
|
-
env
|
60
|
+
flip_routes(env).first.values_at(:hostname, :domain).compact.join(' *')
|
51
61
|
end
|
52
62
|
|
53
|
-
def
|
54
|
-
cf.
|
63
|
+
def live_color(env)
|
64
|
+
cf.live_color(match_flip_route_grep(env))
|
55
65
|
end
|
56
66
|
|
57
|
-
def
|
58
|
-
|
67
|
+
def idle_color(env)
|
68
|
+
if live_color(env) != 'blue'
|
69
|
+
'blue'
|
70
|
+
else
|
71
|
+
'green'
|
72
|
+
end
|
59
73
|
end
|
60
|
-
|
61
74
|
end
|
62
75
|
end
|
63
76
|
end
|
data/lib/cf/deploy/commands.rb
CHANGED
@@ -16,29 +16,32 @@ module CF
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def stop(app_name)
|
19
|
-
|
20
|
-
Kernel.system(stop_cmd)
|
19
|
+
Kernel.system("cf stop #{app_name}")
|
21
20
|
end
|
22
21
|
|
23
22
|
def map_route(route, app_name)
|
24
|
-
|
25
|
-
map_cmd = "#{map_cmd} -n #{route[:hostname]}" unless route[:hostname].nil?
|
26
|
-
Kernel.system(map_cmd)
|
23
|
+
Kernel.system(route_cmd(:map, route, app_name))
|
27
24
|
end
|
28
25
|
|
29
26
|
def unmap_route(route, app_name)
|
30
|
-
|
31
|
-
unmap_cmd = "#{unmap_cmd} -n #{route[:hostname]}" unless route[:hostname].nil?
|
32
|
-
Kernel.system(unmap_cmd)
|
27
|
+
Kernel.system(route_cmd(:unmap, route, app_name))
|
33
28
|
end
|
34
29
|
|
35
|
-
def
|
30
|
+
def live_color(host)
|
36
31
|
io = IO.popen("cf routes | grep '#{host}'")
|
37
32
|
matches = /(blue|green)/.match(io.read)
|
38
33
|
io.close
|
39
34
|
return if matches.nil?
|
40
35
|
matches[1].strip
|
41
36
|
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def route_cmd(method, route, app_name)
|
41
|
+
map_cmd = "cf #{method}-route #{app_name} #{route[:domain]}"
|
42
|
+
map_cmd = "#{map_cmd} -n #{route[:hostname]}" unless route[:hostname].nil?
|
43
|
+
map_cmd
|
44
|
+
end
|
42
45
|
end
|
43
46
|
end
|
44
47
|
end
|
data/lib/cf/deploy/config.rb
CHANGED
@@ -8,12 +8,12 @@ module CF
|
|
8
8
|
def initialize(&block)
|
9
9
|
@environments_to_be_loaded = []
|
10
10
|
|
11
|
-
merge!(:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
11
|
+
merge!(manifest_glob: 'manifests/*',
|
12
|
+
api: nil,
|
13
|
+
username: nil,
|
14
|
+
password: nil,
|
15
|
+
organisation: nil,
|
16
|
+
space: nil)
|
17
17
|
|
18
18
|
instance_eval(&block) if block_given?
|
19
19
|
|
data/lib/cf/deploy/env_config.rb
CHANGED
@@ -9,12 +9,11 @@ module CF
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def initialize(name, deps, manifests, &block)
|
12
|
-
merge!(:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:manifests => manifests)
|
12
|
+
merge!(name: name,
|
13
|
+
task_name: EnvConfig.task_name(name),
|
14
|
+
deps: deps,
|
15
|
+
routes: [],
|
16
|
+
manifests: manifests)
|
18
17
|
|
19
18
|
instance_eval(&block) if block_given?
|
20
19
|
|
@@ -28,9 +27,9 @@ module CF
|
|
28
27
|
end
|
29
28
|
|
30
29
|
def deployment_for_manifest(manifest)
|
31
|
-
{:
|
32
|
-
|
33
|
-
|
30
|
+
{ task_name: deployment_task_name(manifest),
|
31
|
+
manifest: manifest,
|
32
|
+
app_names: app_names_for_manifest(manifest) }
|
34
33
|
end
|
35
34
|
|
36
35
|
def deployment_task_name(manifest)
|
@@ -52,10 +51,10 @@ module CF
|
|
52
51
|
end
|
53
52
|
|
54
53
|
def app_name_for_colour(colour)
|
55
|
-
self[:manifests].map
|
56
|
-
name = app_names_for_manifest(File.expand_path(
|
54
|
+
self[:manifests].map do |manifest|
|
55
|
+
name = app_names_for_manifest(File.expand_path(manifest.to_s)).first
|
57
56
|
return name if name.include?(colour)
|
58
|
-
|
57
|
+
end
|
59
58
|
end
|
60
59
|
|
61
60
|
# Environment config setter methods
|
@@ -68,12 +67,27 @@ module CF
|
|
68
67
|
self[:manifests].concat(manifests)
|
69
68
|
end
|
70
69
|
|
71
|
-
def route(domain,
|
72
|
-
|
70
|
+
def route(domain, hostname_or_options = nil, options = nil)
|
71
|
+
if options.nil?
|
72
|
+
if hostname_or_options.nil?
|
73
|
+
hostname = nil
|
74
|
+
options = {}
|
75
|
+
elsif hostname_or_options.is_a?(String)
|
76
|
+
hostname = hostname_or_options
|
77
|
+
options = {}
|
78
|
+
else
|
79
|
+
hostname = nil
|
80
|
+
options = hostname_or_options
|
81
|
+
end
|
82
|
+
else
|
83
|
+
hostname = hostname_or_options
|
84
|
+
end
|
85
|
+
|
86
|
+
self[:routes] << { domain: domain, hostname: hostname }.merge(options)
|
73
87
|
end
|
74
88
|
|
75
|
-
def flip_route(domain, hostname =nil)
|
76
|
-
self[:
|
89
|
+
def flip_route(domain, hostname = nil)
|
90
|
+
self[:routes] << { domain: domain, hostname: hostname, flip: true }
|
77
91
|
end
|
78
92
|
end
|
79
93
|
end
|
data/lib/cf/deploy/version.rb
CHANGED
@@ -12,8 +12,9 @@ describe CF::Deploy do
|
|
12
12
|
Dir.chdir('spec/') do
|
13
13
|
described_class.rake_tasks! do
|
14
14
|
environment :production do
|
15
|
-
|
16
|
-
|
15
|
+
route 'yourwebsite.com', flip: true
|
16
|
+
route 'yourwebsite.com', 'www', flip: true
|
17
|
+
route 'yourwebsite.com', 'www-origin', flip: true
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
@@ -27,7 +28,7 @@ describe CF::Deploy do
|
|
27
28
|
it 'should deploy blue if not currently deployed' do
|
28
29
|
rake_tasks!
|
29
30
|
expect(Kernel).to receive(:system).with('cf login').ordered
|
30
|
-
expect(IO).to receive(:popen).with("cf routes | grep '
|
31
|
+
expect(IO).to receive(:popen).with("cf routes | grep 'yourwebsite.com'") { double(read: '', close: nil) }
|
31
32
|
expect(Kernel).to receive(:system).with('cf push -f manifests/production_blue.yml').and_return(true).ordered
|
32
33
|
Rake::Task['cf:deploy:production'].invoke
|
33
34
|
end
|
@@ -35,7 +36,7 @@ describe CF::Deploy do
|
|
35
36
|
it 'should deploy blue if green currently deployed' do
|
36
37
|
rake_tasks!
|
37
38
|
expect(Kernel).to receive(:system).with('cf login').ordered
|
38
|
-
expect(IO).to receive(:popen).with("cf routes | grep '
|
39
|
+
expect(IO).to receive(:popen).with("cf routes | grep 'yourwebsite.com'") { double(read: 'production-green-app', close: nil) }
|
39
40
|
expect(Kernel).to receive(:system).with('cf push -f manifests/production_blue.yml').and_return(true).ordered
|
40
41
|
Rake::Task['cf:deploy:production'].invoke
|
41
42
|
end
|
@@ -43,15 +44,15 @@ describe CF::Deploy do
|
|
43
44
|
it 'should deploy green if blue currently deployed' do
|
44
45
|
rake_tasks!
|
45
46
|
expect(Kernel).to receive(:system).with('cf login').ordered
|
46
|
-
expect(IO).to receive(:popen).with("cf routes | grep '
|
47
|
+
expect(IO).to receive(:popen).with("cf routes | grep 'yourwebsite.com'") { double(read: 'production-blue-app', close: nil) }
|
47
48
|
expect(Kernel).to receive(:system).with('cf push -f manifests/production_green.yml').and_return(true).ordered
|
48
49
|
Rake::Task['cf:deploy:production'].invoke
|
49
50
|
end
|
50
51
|
|
51
52
|
it 'should ignore flip_routes' do
|
52
53
|
rake_tasks!
|
53
|
-
expect(Kernel).to_not receive(:system).with('cf map-route production-blue-app yourwebsite.com -n www')
|
54
|
-
expect(Kernel).to_not receive(:system).with('cf map-route production-blue-app yourwebsite.com -n www-origin')
|
54
|
+
expect(Kernel).to_not receive(:system).with('cf map-route production-blue-app yourwebsite.com -n www')
|
55
|
+
expect(Kernel).to_not receive(:system).with('cf map-route production-blue-app yourwebsite.com -n www-origin')
|
55
56
|
end
|
56
57
|
|
57
58
|
it 'should throw exception if no routes defined for blue/green task' do
|
@@ -62,9 +63,7 @@ describe CF::Deploy do
|
|
62
63
|
end
|
63
64
|
|
64
65
|
allow(Kernel).to receive(:system)
|
65
|
-
expect
|
66
|
-
Rake::Task['cf:deploy:production'].invoke
|
67
|
-
end.to raise_error
|
66
|
+
expect { Rake::Task['cf:deploy:production'].invoke }.to raise_error
|
68
67
|
end
|
69
68
|
|
70
69
|
it 'should run prerequisite tasks' do
|
data/spec/flip_task_spec.rb
CHANGED
@@ -8,12 +8,12 @@ describe CF::Deploy do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
context 'Flip production environments' do
|
11
|
-
|
12
11
|
let :rake_tasks! do
|
13
12
|
described_class.rake_tasks! do
|
14
13
|
environment :production do
|
15
|
-
|
16
|
-
|
14
|
+
route 'yourwebsite.com', flip: true
|
15
|
+
route 'yourwebsite.com', 'www', flip: true
|
16
|
+
route 'yourwebsite.com', 'www-origin', flip: true
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
@@ -22,12 +22,18 @@ describe CF::Deploy do
|
|
22
22
|
Dir.chdir('spec/') do
|
23
23
|
rake_tasks!
|
24
24
|
expect(Kernel).to receive(:system).with('cf login').ordered
|
25
|
-
|
25
|
+
|
26
|
+
expect(IO).to receive(:popen).with("cf routes | grep 'yourwebsite.com'") { double(:read => 'production-green-app', :close => nil) }
|
27
|
+
expect(Kernel).to receive(:system).with('cf map-route production-blue-app yourwebsite.com').ordered
|
28
|
+
expect(Kernel).to receive(:system).with('cf unmap-route production-green-app yourwebsite.com').ordered
|
29
|
+
|
30
|
+
expect(IO).to receive(:popen).with("cf routes | grep 'yourwebsite.com'") { double(:read => 'production-green-app', :close => nil) }
|
26
31
|
expect(Kernel).to receive(:system).with('cf map-route production-blue-app yourwebsite.com -n www').ordered
|
27
32
|
expect(Kernel).to receive(:system).with('cf unmap-route production-green-app yourwebsite.com -n www').ordered
|
28
|
-
|
33
|
+
|
29
34
|
expect(Kernel).to receive(:system).with('cf map-route production-blue-app yourwebsite.com -n www-origin').ordered
|
30
35
|
expect(Kernel).to receive(:system).with('cf unmap-route production-green-app yourwebsite.com -n www-origin').ordered
|
36
|
+
|
31
37
|
Rake::Task['cf:deploy:production:flip'].invoke
|
32
38
|
end
|
33
39
|
end
|
@@ -36,16 +42,19 @@ describe CF::Deploy do
|
|
36
42
|
Dir.chdir('spec/') do
|
37
43
|
rake_tasks!
|
38
44
|
expect(Kernel).to receive(:system).with('cf login').ordered
|
39
|
-
|
45
|
+
|
46
|
+
expect(IO).to receive(:popen).with("cf routes | grep 'yourwebsite.com'") { double(:read => 'production-blue-app', :close => nil) }
|
47
|
+
expect(Kernel).to receive(:system).with('cf map-route production-green-app yourwebsite.com').ordered
|
48
|
+
expect(Kernel).to receive(:system).with('cf unmap-route production-blue-app yourwebsite.com').ordered
|
49
|
+
|
50
|
+
expect(IO).to receive(:popen).with("cf routes | grep 'yourwebsite.com'") { double(:read => 'production-blue-app', :close => nil) }
|
40
51
|
expect(Kernel).to receive(:system).with('cf map-route production-green-app yourwebsite.com -n www').ordered
|
41
52
|
expect(Kernel).to receive(:system).with('cf unmap-route production-blue-app yourwebsite.com -n www').ordered
|
42
|
-
|
53
|
+
|
43
54
|
expect(Kernel).to receive(:system).with('cf map-route production-green-app yourwebsite.com -n www-origin').ordered
|
44
55
|
expect(Kernel).to receive(:system).with('cf unmap-route production-blue-app yourwebsite.com -n www-origin').ordered
|
45
56
|
Rake::Task['cf:deploy:production:flip'].invoke
|
46
57
|
end
|
47
58
|
end
|
48
|
-
|
49
59
|
end
|
50
|
-
|
51
60
|
end
|
data/spec/rake_tasks_spec.rb
CHANGED
@@ -34,20 +34,27 @@ describe CF::Deploy do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'should install tasks with prerequisites' do
|
37
|
+
expected_task_0 = Rake::Task.define_task('cf:login')
|
37
38
|
expected_task_1 = Rake::Task.define_task('asset:precompile')
|
38
39
|
expected_task_2 = Rake::Task.define_task(:clean)
|
39
40
|
|
40
41
|
Dir.chdir('spec/') do
|
41
42
|
described_class.rake_tasks! do
|
42
|
-
environment :
|
43
|
-
environment :
|
44
|
-
environment :
|
43
|
+
environment staging: 'asset:precompile'
|
44
|
+
environment test: ['asset:precompile', :clean]
|
45
|
+
environment production: 'asset:precompile' do
|
46
|
+
route 'app'
|
47
|
+
end
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
48
51
|
expect(Rake::Task['cf:deploy:staging'].prerequisite_tasks[1]).to be(expected_task_1)
|
49
52
|
expect(Rake::Task['cf:deploy:test'].prerequisite_tasks[2]).to be(expected_task_2)
|
50
53
|
expect(Rake::Task['cf:deploy:production'].prerequisite_tasks[1]).to be(expected_task_1)
|
54
|
+
expect(Rake::Task['cf:deploy:production_blue'].prerequisite_tasks[1]).to be(expected_task_1)
|
55
|
+
expect(Rake::Task['cf:deploy:production_green'].prerequisite_tasks[1]).to be(expected_task_1)
|
56
|
+
expect(Rake::Task['cf:deploy:production:flip'].prerequisite_tasks[0]).to be(expected_task_0)
|
57
|
+
expect(Rake::Task['cf:deploy:production:stop_idle'].prerequisite_tasks[0]).to be(expected_task_0)
|
51
58
|
end
|
52
59
|
|
53
60
|
it 'should have a configurable manifest glob options' do
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'cf-deploy'
|
3
|
+
require 'rake'
|
4
|
+
|
5
|
+
describe CF::Deploy do
|
6
|
+
before :each do
|
7
|
+
Rake::Task.clear
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'Suspend idle app' do
|
11
|
+
let :rake_tasks! do
|
12
|
+
described_class.rake_tasks! do
|
13
|
+
environment :production do
|
14
|
+
route 'yourwebsite.com', flip: true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should stop green if green is currently mapped' do
|
20
|
+
Dir.chdir('spec/') do
|
21
|
+
rake_tasks!
|
22
|
+
expect(Kernel).to receive(:system).with('cf login').ordered
|
23
|
+
expect(Kernel).to receive(:system).with('cf stop production-blue-app').ordered
|
24
|
+
Rake::Task['cf:deploy:production:stop_idle'].invoke
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should stop to blue if blue is currently mapped' do
|
29
|
+
Dir.chdir('spec/') do
|
30
|
+
rake_tasks!
|
31
|
+
expect(Kernel).to receive(:system).with('cf login').ordered
|
32
|
+
expect(IO).to receive(:popen).with("cf routes | grep 'yourwebsite.com'") { double(:read => 'production-blue-app', :close => nil) }
|
33
|
+
expect(Kernel).to receive(:system).with('cf stop production-green-app').ordered
|
34
|
+
Rake::Task['cf:deploy:production:stop_idle'].invoke
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
metadata
CHANGED
@@ -1,32 +1,36 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cf-deploy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Luke Morton
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2015-03-24 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: rake
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- - '>='
|
19
|
+
- - ! '>='
|
18
20
|
- !ruby/object:Gem::Version
|
19
21
|
version: '0'
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
|
-
- - '>='
|
27
|
+
- - ! '>='
|
25
28
|
- !ruby/object:Gem::Version
|
26
29
|
version: '0'
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: bundler
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
35
|
- - ~>
|
32
36
|
- !ruby/object:Gem::Version
|
@@ -34,6 +38,7 @@ dependencies:
|
|
34
38
|
type: :development
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
43
|
- - ~>
|
39
44
|
- !ruby/object:Gem::Version
|
@@ -41,6 +46,7 @@ dependencies:
|
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: rspec
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
51
|
- - ~>
|
46
52
|
- !ruby/object:Gem::Version
|
@@ -48,6 +54,7 @@ dependencies:
|
|
48
54
|
type: :development
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
51
58
|
requirements:
|
52
59
|
- - ~>
|
53
60
|
- !ruby/object:Gem::Version
|
@@ -55,6 +62,7 @@ dependencies:
|
|
55
62
|
- !ruby/object:Gem::Dependency
|
56
63
|
name: simplecov
|
57
64
|
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
58
66
|
requirements:
|
59
67
|
- - ~>
|
60
68
|
- !ruby/object:Gem::Version
|
@@ -62,6 +70,7 @@ dependencies:
|
|
62
70
|
type: :development
|
63
71
|
prerelease: false
|
64
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
65
74
|
requirements:
|
66
75
|
- - ~>
|
67
76
|
- !ruby/object:Gem::Version
|
@@ -69,15 +78,17 @@ dependencies:
|
|
69
78
|
- !ruby/object:Gem::Dependency
|
70
79
|
name: codeclimate-test-reporter
|
71
80
|
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
72
82
|
requirements:
|
73
|
-
- - '>='
|
83
|
+
- - ! '>='
|
74
84
|
- !ruby/object:Gem::Version
|
75
85
|
version: '0'
|
76
86
|
type: :development
|
77
87
|
prerelease: false
|
78
88
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
79
90
|
requirements:
|
80
|
-
- - '>='
|
91
|
+
- - ! '>='
|
81
92
|
- !ruby/object:Gem::Version
|
82
93
|
version: '0'
|
83
94
|
description:
|
@@ -100,30 +111,38 @@ files:
|
|
100
111
|
- spec/login_task_spec.rb
|
101
112
|
- spec/rake_tasks_spec.rb
|
102
113
|
- spec/spec_helper.rb
|
114
|
+
- spec/stop_idle_task_spec.rb
|
103
115
|
- LICENSE
|
104
116
|
- README.md
|
105
117
|
homepage: https://github.com/madebymade/cf-deploy
|
106
118
|
licenses:
|
107
119
|
- MIT
|
108
|
-
metadata: {}
|
109
120
|
post_install_message:
|
110
121
|
rdoc_options: []
|
111
122
|
require_paths:
|
112
123
|
- lib
|
113
124
|
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
114
126
|
requirements:
|
115
|
-
- - '>='
|
127
|
+
- - ! '>='
|
116
128
|
- !ruby/object:Gem::Version
|
117
129
|
version: '0'
|
130
|
+
segments:
|
131
|
+
- 0
|
132
|
+
hash: -2725312878394451314
|
118
133
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
none: false
|
119
135
|
requirements:
|
120
|
-
- - '>='
|
136
|
+
- - ! '>='
|
121
137
|
- !ruby/object:Gem::Version
|
122
138
|
version: '0'
|
139
|
+
segments:
|
140
|
+
- 0
|
141
|
+
hash: -2725312878394451314
|
123
142
|
requirements: []
|
124
143
|
rubyforge_project:
|
125
|
-
rubygems_version:
|
144
|
+
rubygems_version: 1.8.23
|
126
145
|
signing_key:
|
127
|
-
specification_version:
|
146
|
+
specification_version: 3
|
128
147
|
summary: Rake tasks for deploying to CloudFoundry v6+
|
129
148
|
test_files: []
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 7fdd5ef4f413ab5caec0fd8d6a52a23a04cf7b3f
|
4
|
-
data.tar.gz: 2746b6d22beb57314cec0c099fef9f6619c3c6e0
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 1efac37c88afe74c86a13feab83b4bc5fa52f7d28d84ae6b8fe93eb6d655b000f6ffeaee101353512066e826060141029d4de5160aca4771c858ef3f86769934
|
7
|
-
data.tar.gz: 59290656c37a5e1b4834ffd6053bb99ef2296bfbda21f0c7ec3e8f0048e9d19fcbdb1011c71f6323a5892f74bcb9b07a4cd820ecb4f87f6abc064af76189177c
|