prima-twig 0.2.27 → 0.3.0
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 +4 -4
- data/bin/twig-feature +477 -327
- data/bin/twig-open-pr +1 -11
- data/bin/twig-pick-issue +21 -29
- data/lib/prima_twig.rb +10 -3
- metadata +22 -24
- data/bin/twig-release +0 -227
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76aeaf72c0f6f23b244156bcd17bd599d4740ac8
|
4
|
+
data.tar.gz: fe846e2f48d383ee1b2f7a676b72139d578f001f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67d67bf6c16e34bbb93990e8f8f1b3ca39f6f5afd9474d74c26091b05228059bdbb843e571a8c4aeefc14747dc0589899d9699a1da38b52ebe1f565538e3bf2b
|
7
|
+
data.tar.gz: f97e7ceeb4246ebf87465e3488c223997337c43f20afdddd92a95fad8d8a23c648d6655e92358333293439f7149550f7ea07b13b9fb7ae50e8e44f3a3359ee7b
|
data/bin/twig-feature
CHANGED
@@ -3,34 +3,33 @@
|
|
3
3
|
require 'rubygems'
|
4
4
|
require_relative '../lib/prima_twig.rb'
|
5
5
|
require 'launchy'
|
6
|
+
require 'digest'
|
7
|
+
require 'pp'
|
6
8
|
|
7
9
|
class Release
|
8
10
|
include Command
|
9
11
|
|
10
12
|
def initialize
|
11
13
|
@prima = Prima.new
|
12
|
-
@
|
14
|
+
@cf = Aws::CloudFormation::Client.new
|
15
|
+
@elb = Aws::ElasticLoadBalancing::Client.new
|
13
16
|
@ec2 = Aws::EC2::Client.new
|
14
|
-
@
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@environment_name = sanitize_environment_name(@s3_key.gsub('.zip', ''))
|
19
|
-
@git_rev = `git rev-parse HEAD`
|
20
|
-
@version_label = @environment_name + '-' + @git_rev[0,5]
|
21
|
-
@user = `git config user.name`.downcase
|
22
|
-
@user = @user[0,1] + @user.split(' ').last
|
17
|
+
@ecs = Aws::ECS::Client.new
|
18
|
+
@s3 = Aws::S3::Client.new
|
19
|
+
@asg = Aws::AutoScaling::Client.new
|
20
|
+
@s3_bucket = 'prima-artifacts'
|
23
21
|
@artifact_path = '/tmp/prima-artifact.zip'
|
24
|
-
@
|
25
|
-
@
|
22
|
+
@qa_cluster = 'ecs-cluster-qa-ECSCluster-ROF3QJNLOXGG'
|
23
|
+
@import_db_task = 'arn:aws:ecs:eu-west-1:001575623345:task-definition/ecs-task-dbrestore-TaskDefinitionDbRestore-2NOTCW35ZOTF:1'
|
24
|
+
@prima_built = false
|
25
|
+
@urania_built = false
|
26
|
+
@backoffice_built = false
|
26
27
|
end
|
27
28
|
|
28
29
|
def execute! args
|
29
|
-
possible_args = ["
|
30
|
+
possible_args = ["deploy"]
|
30
31
|
stop_if args.empty?, [:wrong_args, possible_args]
|
31
|
-
stop_if args.length >
|
32
|
-
|
33
|
-
stop_if @prima.head_detached?, :detached_head
|
32
|
+
stop_if args.length > 1, [:wrong_args, possible_args]
|
34
33
|
|
35
34
|
case args[0]
|
36
35
|
when "start"
|
@@ -41,8 +40,7 @@ class Release
|
|
41
40
|
if ['terminate', 'stop', 'shutdown', 'halt', 'destroy'].include? args[1]
|
42
41
|
deploy_shutdown!
|
43
42
|
else
|
44
|
-
|
45
|
-
deploy_feature! ignoranza
|
43
|
+
deploy_feature!
|
46
44
|
end
|
47
45
|
else
|
48
46
|
stop_if true, [:wrong_args, possible_args]
|
@@ -50,119 +48,274 @@ class Release
|
|
50
48
|
end
|
51
49
|
|
52
50
|
def start_feature!
|
51
|
+
branch_name = @prima.clean_branch_name(ask('Inserisci il nome del branch (puoi omettere feature/): '.cyan))
|
52
|
+
stop_unless branch_name.length > 0, 'Devi inserire il nome del branch'
|
53
|
+
branch_name.prepend 'feature/' unless branch_name.include? 'feature'
|
54
|
+
|
55
|
+
output "Il nome del branch sarà " + branch_name.yellow
|
56
|
+
|
57
|
+
exec_step "git checkout master"
|
58
|
+
exec_step "git pull origin master"
|
59
|
+
exec_step "git checkout -b " + branch_name
|
53
60
|
end
|
54
61
|
|
55
62
|
def finish_feature!
|
56
|
-
|
63
|
+
current_branch_name = @prima.twig.current_branch_name
|
64
|
+
stop_unless (current_branch_name =~ /^feature\//), "Non sei su un branch di feature, non posso mergiare nulla"
|
57
65
|
|
58
|
-
|
66
|
+
# Mergia la PR
|
67
|
+
pr = @prima.get_pr
|
68
|
+
stop_unless pr, 'Pull Request not found'
|
69
|
+
@prima.merge_pull_request pr
|
59
70
|
|
60
|
-
|
71
|
+
output "La Pull Request e' stata mergiata!".green
|
61
72
|
|
62
|
-
|
73
|
+
# Chiude la issue
|
74
|
+
issue_number = @prima.twig.get_branch_property(current_branch_name, 'issue')
|
75
|
+
@prima.close_issue(issue_number) if issue_number
|
63
76
|
|
64
|
-
|
77
|
+
# Rimuove il branch remoto
|
78
|
+
exec_step "git push origin :#{current_branch_name}" if @prima.yesno "Vuoi eliminare il branch remoto #{current_branch_name}?".blue
|
79
|
+
end
|
65
80
|
|
66
|
-
|
67
|
-
|
81
|
+
def deploy_shutdown!
|
82
|
+
output "Not implemented yet!".red
|
83
|
+
exit
|
84
|
+
# stop_unless environment_exists?(@application_name, @environment_name), "L'environment #{@environment_name} non esiste!"
|
85
|
+
# shutdown_environment(@environment_name) if @prima.yesno("Sei sicuro di voler spegnere l'env?".blue)
|
86
|
+
# output "L'environment #{@environment_name} e' stato disrutto con successo!\n".green
|
87
|
+
# output "Potrebbe comunque passare qualche minuto prima che l'operazione finisca\n".yellow
|
88
|
+
end
|
68
89
|
|
69
|
-
|
70
|
-
|
90
|
+
def deploy_feature!
|
91
|
+
prima_branch = choose_branch_to_deploy('prima')
|
92
|
+
backoffice_branch = choose_branch_to_deploy('backoffice')
|
93
|
+
urania_branch = choose_branch_to_deploy('urania')
|
94
|
+
socket_branch = {name: "master"}
|
95
|
+
pamela_branch = {name: "master"}
|
96
|
+
|
97
|
+
tags = [
|
98
|
+
{
|
99
|
+
key: "prima",
|
100
|
+
value: prima_branch[:name]
|
101
|
+
},
|
102
|
+
{
|
103
|
+
key: "urania",
|
104
|
+
value: urania_branch[:name]
|
105
|
+
},
|
106
|
+
{
|
107
|
+
key: "backoffice",
|
108
|
+
value: backoffice_branch[:name]
|
109
|
+
}
|
110
|
+
]
|
111
|
+
|
112
|
+
deploy_id = Digest::MD5.hexdigest(prima_branch[:name] + backoffice_branch[:name] + urania_branch[:name] + socket_branch[:name] + pamela_branch[:name])
|
113
|
+
|
114
|
+
asg_stack_name = "ecs-asg-allinone-qa-#{deploy_id}"
|
115
|
+
create_asg_stack(asg_stack_name) unless stack_exists?(asg_stack_name)
|
116
|
+
|
117
|
+
stack_name_db = "ecs-task-db-qa-#{deploy_id}"
|
118
|
+
stack_body = IO.read('cloudformation/stacks/task/db.json')
|
119
|
+
parameters = [
|
120
|
+
{
|
121
|
+
parameter_key: "Environment",
|
122
|
+
parameter_value: "qa"
|
123
|
+
}
|
124
|
+
]
|
125
|
+
create_stack(stack_name_db, stack_body, parameters, tags) unless stack_exists?(stack_name_db)
|
126
|
+
|
127
|
+
create_prima_artifact(prima_branch[:revision]) unless artifact_exists?('prima-artifacts', "prima/#{prima_branch[:revision]}")
|
128
|
+
create_urania_artifact(urania_branch[:revision]) unless artifact_exists?('prima-artifacts', "microservices/urania/#{urania_branch[:revision]}-qa.tar.gz")
|
129
|
+
|
130
|
+
wait_for_stack_ready(stack_name_db) unless stack_ready?(stack_name_db)
|
131
|
+
|
132
|
+
import_dbs unless stack_exists?("ecs-task-web-qa-#{deploy_id}")
|
133
|
+
|
134
|
+
stack_name_web = "ecs-task-web-qa-#{deploy_id}"
|
135
|
+
git_checkout_version('prima', prima_branch[:revision])
|
136
|
+
stack_body = IO.read('projects/prima/app/cloudformation/tasks/web.json')
|
137
|
+
parameters = [
|
138
|
+
{
|
139
|
+
parameter_key: "Environment",
|
140
|
+
parameter_value: "qa"
|
141
|
+
},
|
142
|
+
{
|
143
|
+
parameter_key: "ReleaseVersion",
|
144
|
+
parameter_value: prima_branch[:revision]
|
145
|
+
},
|
146
|
+
{
|
147
|
+
parameter_key: "TaskDesiredCount",
|
148
|
+
parameter_value: "1"
|
149
|
+
}
|
150
|
+
]
|
151
|
+
if stack_exists?(stack_name_web)
|
152
|
+
update_stack(stack_name_web, stack_body, parameters) if @prima_built
|
71
153
|
else
|
72
|
-
|
154
|
+
create_stack(stack_name_web, stack_body, parameters, tags)
|
73
155
|
end
|
74
156
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
157
|
+
stack_name_consumer = "ecs-task-consumer-qa-#{deploy_id}"
|
158
|
+
git_checkout_version('prima', prima_branch[:revision])
|
159
|
+
stack_body = IO.read('projects/prima/app/cloudformation/tasks/consumer.json')
|
160
|
+
parameters = [
|
161
|
+
{
|
162
|
+
parameter_key: "Environment",
|
163
|
+
parameter_value: "qa"
|
164
|
+
},
|
165
|
+
{
|
166
|
+
parameter_key: "ReleaseVersion",
|
167
|
+
parameter_value: prima_branch[:revision]
|
168
|
+
}
|
169
|
+
]
|
170
|
+
if stack_exists?(stack_name_consumer)
|
171
|
+
update_stack(stack_name_consumer, stack_body, parameters) if @prima_built
|
172
|
+
else
|
173
|
+
create_stack(stack_name_consumer, stack_body, parameters, tags)
|
174
|
+
end
|
80
175
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
176
|
+
stack_name_urania = "ecs-task-urania-qa-#{deploy_id}"
|
177
|
+
git_checkout_version('urania', urania_branch[:revision])
|
178
|
+
stack_body = IO.read('projects/urania/deploy/task.json')
|
179
|
+
parameters = [
|
180
|
+
{
|
181
|
+
parameter_key: "Environment",
|
182
|
+
parameter_value: "qa"
|
183
|
+
},
|
184
|
+
{
|
185
|
+
parameter_key: "ReleaseVersion",
|
186
|
+
parameter_value: urania_branch[:revision]
|
187
|
+
},
|
188
|
+
{
|
189
|
+
parameter_key: "TaskDesiredCount",
|
190
|
+
parameter_value: "1"
|
191
|
+
}
|
192
|
+
]
|
193
|
+
if stack_exists?(stack_name_urania)
|
194
|
+
update_stack(stack_name_urania, stack_body, parameters) if @urania_built
|
195
|
+
else
|
196
|
+
create_stack(stack_name_urania, stack_body, parameters, tags)
|
197
|
+
end
|
87
198
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
resp = @eb.create_application_version({
|
98
|
-
application_name: @application_name,
|
99
|
-
version_label: @version_label,
|
100
|
-
description: @current_branch_name,
|
101
|
-
source_bundle: {
|
102
|
-
s3_bucket: @s3_bucket,
|
103
|
-
s3_key: @s3_key,
|
199
|
+
# Dev'essere fatto qua perche' dipende dall'url di web
|
200
|
+
create_backoffice_artifact(backoffice_branch[:revision], deploy_id) unless artifact_exists?('prima-artifacts', "backoffice/#{backoffice_branch[:revision]}-#{deploy_id}.zip")
|
201
|
+
git_checkout_version('backoffice', backoffice_branch[:revision])
|
202
|
+
stack_name_backoffice = "ecs-task-backoffice-qa-#{deploy_id}"
|
203
|
+
stack_body = IO.read('projects/backoffice/deploy/task.json')
|
204
|
+
parameters = [
|
205
|
+
{
|
206
|
+
parameter_key: "Environment",
|
207
|
+
parameter_value: "qa"
|
104
208
|
},
|
105
|
-
|
106
|
-
|
209
|
+
{
|
210
|
+
parameter_key: "ReleaseVersion",
|
211
|
+
parameter_value: "#{backoffice_branch[:revision]}-#{deploy_id}"
|
212
|
+
},
|
213
|
+
{
|
214
|
+
parameter_key: "TaskDesiredCount",
|
215
|
+
parameter_value: "1"
|
216
|
+
}
|
217
|
+
]
|
218
|
+
if stack_exists?(stack_name_backoffice)
|
219
|
+
update_stack(stack_name_backoffice, stack_body, parameters) if @backoffice_built
|
220
|
+
else
|
221
|
+
create_stack(stack_name_backoffice, stack_body, parameters, tags)
|
222
|
+
end
|
107
223
|
|
108
|
-
|
224
|
+
wait_for_stack_ready(stack_name_web) unless stack_ready?(stack_name_web)
|
225
|
+
wait_for_stack_ready(stack_name_consumer) unless stack_ready?(stack_name_consumer)
|
226
|
+
wait_for_stack_ready(stack_name_urania) unless stack_ready?(stack_name_urania)
|
227
|
+
wait_for_stack_ready(stack_name_backoffice) unless stack_ready?(stack_name_backoffice)
|
109
228
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
229
|
+
update_service_defaults(stack_name_web)
|
230
|
+
update_service_defaults(stack_name_consumer)
|
231
|
+
update_service_defaults(stack_name_urania)
|
232
|
+
update_service_defaults(stack_name_backoffice)
|
233
|
+
|
234
|
+
prima_elb_url = get_elb_url(stack_name_web)
|
235
|
+
urania_elb_url = get_elb_url(stack_name_urania)
|
236
|
+
backoffice_elb_url = get_elb_url(stack_name_backoffice)
|
237
|
+
|
238
|
+
output "Prima url: #{prima_elb_url}\n".cyan
|
239
|
+
output "Urania url: #{urania_elb_url}\n".cyan
|
240
|
+
output "Backoffice url: #{backoffice_elb_url}\n".cyan
|
241
|
+
output "SSH connection: ssh ec2-user@#{ec2_ip_address(asg_stack_name)} -i ~/.ssh/ecs-cluster-qa.pem".cyan
|
242
|
+
output "Deploy effettuato, everything is awesome!\n".green
|
243
|
+
end
|
244
|
+
|
245
|
+
def ec2_ip_address(asg_stack_name)
|
246
|
+
resp = @cf.describe_stack_resource({
|
247
|
+
stack_name: asg_stack_name,
|
248
|
+
logical_resource_id: 'ECSAutoScalingGroup'
|
249
|
+
})
|
250
|
+
resp = @asg.describe_auto_scaling_groups({
|
251
|
+
auto_scaling_group_names: [resp.stack_resource_detail.physical_resource_id],
|
252
|
+
max_records: 1
|
253
|
+
})
|
254
|
+
instance_id = resp.auto_scaling_groups[0].instances[0].instance_id
|
255
|
+
resp = @ec2.describe_instances({instance_ids: [instance_id]})
|
256
|
+
resp.reservations[0].instances[0].private_ip_address
|
257
|
+
end
|
258
|
+
|
259
|
+
def get_elb_url(stack_name)
|
260
|
+
case
|
261
|
+
when stack_name.include?('web')
|
262
|
+
logical_resource_id = 'EcsElasticLoadBalancerPublic'
|
263
|
+
when stack_name.include?('urania')
|
264
|
+
logical_resource_id = 'EcsElasticLoadBalancerInternal'
|
265
|
+
when stack_name.include?('backoffice')
|
266
|
+
logical_resource_id = 'EcsElasticLoadBalancerPublic'
|
136
267
|
end
|
268
|
+
resp = @cf.describe_stack_resource({
|
269
|
+
stack_name: stack_name,
|
270
|
+
logical_resource_id: logical_resource_id
|
271
|
+
})
|
272
|
+
resp = @elb.describe_load_balancers({
|
273
|
+
load_balancer_names: [resp.stack_resource_detail.physical_resource_id],
|
274
|
+
page_size: 1
|
275
|
+
})
|
276
|
+
resp.load_balancer_descriptions[0].dns_name
|
137
277
|
end
|
138
278
|
|
139
|
-
def
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
279
|
+
def update_service_defaults(stack_name)
|
280
|
+
case
|
281
|
+
when stack_name.include?('web')
|
282
|
+
logical_resource_id = 'ECSServiceWeb'
|
283
|
+
when stack_name.include?('consumer')
|
284
|
+
logical_resource_id = 'ECSServiceConsumer'
|
285
|
+
when stack_name.include?('urania')
|
286
|
+
logical_resource_id = 'ECSServiceUrania'
|
287
|
+
when stack_name.include?('backoffice')
|
288
|
+
logical_resource_id = 'ECSServiceBackoffice'
|
147
289
|
else
|
148
|
-
|
290
|
+
raise "Service name non gestito per lo stack #{stack_name}"
|
149
291
|
end
|
292
|
+
resp = @cf.describe_stack_resource({
|
293
|
+
stack_name: stack_name,
|
294
|
+
logical_resource_id: logical_resource_id
|
295
|
+
})
|
296
|
+
resp = @ecs.update_service({
|
297
|
+
cluster: @qa_cluster,
|
298
|
+
service: resp.stack_resource_detail.physical_resource_id,
|
299
|
+
deployment_configuration: {
|
300
|
+
minimum_healthy_percent: 0,
|
301
|
+
maximum_percent: 100
|
302
|
+
}
|
303
|
+
})
|
150
304
|
end
|
151
305
|
|
152
|
-
def
|
306
|
+
def create_urania_artifact(revision)
|
307
|
+
@urania_built = true
|
153
308
|
output "Preparo l'artifact .zip\n".yellow
|
154
309
|
|
155
|
-
|
310
|
+
git_checkout_version('urania', revision)
|
311
|
+
|
312
|
+
Dir.chdir 'projects/urania'
|
313
|
+
|
156
314
|
[
|
157
|
-
"docker run -v $PWD:/
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
"#{base_cmd}php_1 ./app/console -e=prod cypress:ng-routing:dump",
|
162
|
-
"#{base_cmd}php_1 ./app/console -e=prod bazinga:js-translation:dump web",
|
163
|
-
"#{base_cmd}php_1 ./node_modules/.bin/brunch build -e staging",
|
164
|
-
"#{base_cmd}web_1 composer dump-autoload --optimize --no-dev",
|
165
|
-
"#{base_cmd}compass_1 compass compile --force -c compass/config_prod.rb compass/"
|
315
|
+
"docker run -v $PWD:/code -w /code -e MIX_ENV=qa prima/urania:1.0.2 \
|
316
|
+
'mix local.hex --force && mix hex.info && \
|
317
|
+
mix deps.get && mix compile && mix deps.compile && \
|
318
|
+
mix release.clean --implode --no-confirm && mix release'",
|
166
319
|
].each do |cmd|
|
167
320
|
output "Eseguo #{cmd}".yellow
|
168
321
|
res = %x[ #{cmd} ]
|
@@ -174,195 +327,129 @@ class Release
|
|
174
327
|
output res.send color
|
175
328
|
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
176
329
|
end
|
177
|
-
end
|
178
330
|
|
179
|
-
|
180
|
-
|
181
|
-
application_name: application_name,
|
182
|
-
environment_names: [environment_name],
|
183
|
-
include_deleted: false
|
184
|
-
})
|
185
|
-
!resp.environments[0].nil?
|
186
|
-
end
|
331
|
+
artifact_path = Dir.glob("rel/urania/releases/*/urania.tar.gz").first
|
332
|
+
upload_artifact(artifact_path, "microservices/urania/#{revision}-qa.tar.gz")
|
187
333
|
|
188
|
-
|
189
|
-
@eb.terminate_environment({
|
190
|
-
environment_name: environment_name,
|
191
|
-
terminate_resources: true
|
192
|
-
})
|
334
|
+
Dir.chdir '../../'
|
193
335
|
end
|
194
336
|
|
195
|
-
def
|
196
|
-
|
197
|
-
|
198
|
-
stop_unless @prima.yesno("Sei sicuro di voler creare la chiave SSH in #{path}?".blue), "Non puoi continuare senza chiave SSH".red
|
199
|
-
%x[ ssh-keygen -b 2048 -t rsa -f #{path} -q -N '' ]
|
200
|
-
upload_ssh_public_key(ec2_key_name, path + '.pub')
|
201
|
-
output "Chiave SSH creata e uploadata con successo!\n".green
|
202
|
-
end
|
337
|
+
def create_backoffice_artifact(revision, deploy_id)
|
338
|
+
@backoffice_built = true
|
339
|
+
output "Preparo l'artifact .zip\n".yellow
|
203
340
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
key_name: ec2_key_name,
|
208
|
-
public_key_material: IO.read(path)
|
209
|
-
})
|
210
|
-
end
|
341
|
+
git_checkout_version('backoffice', revision)
|
342
|
+
|
343
|
+
Dir.chdir 'projects/backoffice'
|
211
344
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
resp.solution_stacks.each do |solution_stack|
|
217
|
-
match = solution_stack.match(/64bit Amazon Linux [\d\.]+ v([\d\.]+) running Multi-container Docker [\d\.]+ \(Generic\)/i)
|
218
|
-
if match
|
219
|
-
version = match.captures.first
|
220
|
-
if Gem::Version.new(version) > Gem::Version.new(latest_solution_stack[:version])
|
221
|
-
latest_solution_stack[:name] = solution_stack
|
222
|
-
latest_solution_stack[:version] = version
|
345
|
+
['node_modules'].each do |dir|
|
346
|
+
unless File.directory?(dir)
|
347
|
+
if File.directory?("../../../backoffice/#{dir}")
|
348
|
+
exec_step "rsync -a ../../../backoffice/#{dir} ."
|
223
349
|
end
|
224
350
|
end
|
225
351
|
end
|
226
|
-
stop_if latest_solution_stack[:name].empty?, "Solution stack non trovata!".red
|
227
|
-
resp = @eb.create_environment({
|
228
|
-
application_name: application_name,
|
229
|
-
environment_name: environment_name,
|
230
|
-
version_label: version_label,
|
231
|
-
solution_stack_name: latest_solution_stack[:name],
|
232
|
-
option_settings: [
|
233
|
-
{
|
234
|
-
namespace: "aws:ec2:vpc",
|
235
|
-
option_name: "VPCId",
|
236
|
-
value: "vpc-72e52b17",
|
237
|
-
},
|
238
|
-
{
|
239
|
-
namespace: "aws:ec2:vpc",
|
240
|
-
option_name: "Subnets",
|
241
|
-
value: "subnet-90dc64f5,subnet-df13e986,subnet-78db7a0f",
|
242
|
-
},
|
243
|
-
{
|
244
|
-
namespace: "aws:ec2:vpc",
|
245
|
-
option_name: "ELBSubnets",
|
246
|
-
value: "subnet-90dc64f5,subnet-df13e986,subnet-78db7a0f",
|
247
|
-
},
|
248
|
-
{
|
249
|
-
namespace: "aws:ec2:vpc",
|
250
|
-
option_name: "AssociatePublicIpAddress",
|
251
|
-
value: "true",
|
252
|
-
},
|
253
|
-
{
|
254
|
-
namespace: "aws:autoscaling:launchconfiguration",
|
255
|
-
option_name: "SecurityGroups",
|
256
|
-
value: "sg-4079f725",
|
257
|
-
},
|
258
|
-
{
|
259
|
-
namespace: "aws:autoscaling:launchconfiguration",
|
260
|
-
option_name: "IamInstanceProfile",
|
261
|
-
value: "prima-qa",
|
262
|
-
},
|
263
|
-
{
|
264
|
-
namespace: "aws:autoscaling:launchconfiguration",
|
265
|
-
option_name: "EC2KeyName",
|
266
|
-
value: ec2_key_name,
|
267
|
-
},
|
268
|
-
{
|
269
|
-
namespace: "aws:autoscaling:launchconfiguration",
|
270
|
-
option_name: "InstanceType",
|
271
|
-
value: "t2.medium",
|
272
|
-
},
|
273
|
-
{
|
274
|
-
namespace: "aws:autoscaling:asg",
|
275
|
-
option_name: "MaxSize",
|
276
|
-
value: "1",
|
277
|
-
},
|
278
|
-
{
|
279
|
-
namespace: "aws:autoscaling:asg",
|
280
|
-
option_name: "MinSize",
|
281
|
-
value: "1",
|
282
|
-
},
|
283
|
-
{
|
284
|
-
namespace: "aws:cloudformation:template:parameter",
|
285
|
-
option_name: "EnvironmentVariables",
|
286
|
-
value: "SYMFONY__PRIMA__GIT__REVISION=#{git_rev},PRIMA_ENV_NAME=web-qa,PARAMETERS_FILE=prima-deploy/parameters_qa.yml,SYMFONY_ENV=qa,PRIMA_ROLE=all",
|
287
|
-
},
|
288
|
-
{
|
289
|
-
namespace: "aws:elasticbeanstalk:application:environment",
|
290
|
-
option_name: "PARAMETERS_FILE",
|
291
|
-
value: "prima-deploy/parameters_qa.yml",
|
292
|
-
},
|
293
|
-
{
|
294
|
-
namespace: "aws:elasticbeanstalk:application:environment",
|
295
|
-
option_name: "PRIMA_ENV_NAME",
|
296
|
-
value: "web-qa",
|
297
|
-
},
|
298
|
-
{
|
299
|
-
namespace: "aws:elasticbeanstalk:application:environment",
|
300
|
-
option_name: "SYMFONY__PRIMA__GIT__REVISION",
|
301
|
-
value: git_rev,
|
302
|
-
}
|
303
|
-
],
|
304
|
-
tags: [
|
305
|
-
{
|
306
|
-
key: "user",
|
307
|
-
value: @user
|
308
|
-
}
|
309
|
-
]
|
310
|
-
})
|
311
|
-
end
|
312
352
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
environment_names: [environment_name],
|
317
|
-
include_deleted: false
|
318
|
-
})
|
319
|
-
resp.environments[0].status != 'Launching'
|
320
|
-
end
|
353
|
+
stack_name_web = "ecs-task-web-qa-#{deploy_id}"
|
354
|
+
wait_for_stack_ready(stack_name_web) unless stack_ready?(stack_name_web)
|
355
|
+
web_qa_host = get_elb_url(stack_name_web)
|
321
356
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
357
|
+
[
|
358
|
+
"docker-compose build workers",
|
359
|
+
"cd ../../ && docker run -e GIT_DIR=$PWD -v $PWD:/usr/app/src -w /usr/app/src/projects/backoffice blinkmobile/bower install --allow-root",
|
360
|
+
"docker run -v $PWD:/code -w /code --entrypoint /bin/bash backoffice_workers '-c' 'sed -i \"s/web-qa-url/#{web_qa_host}/g\" Gruntfile.js && npm install && grunt qa'",
|
361
|
+
].each do |cmd|
|
362
|
+
output "Eseguo #{cmd}".yellow
|
363
|
+
res = %x[ #{cmd} ]
|
364
|
+
if $?.exitstatus != 0
|
365
|
+
color = 'red'
|
366
|
+
else
|
367
|
+
color = 'green'
|
368
|
+
end
|
369
|
+
output res.send color
|
370
|
+
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
371
|
+
end
|
330
372
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
environment_name: environment_name,
|
337
|
-
start_time: start_time,
|
338
|
-
end_time: end_time
|
339
|
-
})
|
340
|
-
resp.events.reverse
|
373
|
+
artifact_path = '/tmp/backoffice.zip'
|
374
|
+
exec_step "rm -f #{artifact_path} && zip -9 -r #{artifact_path} bin/"
|
375
|
+
upload_artifact(artifact_path, "backoffice/#{revision}-#{deploy_id}.zip")
|
376
|
+
|
377
|
+
Dir.chdir '../../'
|
341
378
|
end
|
342
379
|
|
343
|
-
def
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
while !ready
|
349
|
-
events = get_eb_events(application_name, environment_name, start_time)
|
350
|
-
start_time = Time.now
|
380
|
+
def create_prima_artifact(revision)
|
381
|
+
@prima_built = true
|
382
|
+
output "Preparo l'artifact .zip\n".yellow
|
383
|
+
|
384
|
+
git_checkout_version('prima', revision)
|
351
385
|
|
352
|
-
|
353
|
-
STDOUT.flush
|
386
|
+
Dir.chdir 'projects/prima'
|
354
387
|
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
color = 'cyan'
|
388
|
+
['vendor', 'node_modules'].each do |dir|
|
389
|
+
unless File.directory?(dir)
|
390
|
+
if File.directory?("../../../prima/#{dir}")
|
391
|
+
exec_step "rsync -a ../../../prima/#{dir} ."
|
360
392
|
end
|
361
|
-
output "#{event.event_date} - #{event.severity} #{event.message}".send color
|
362
393
|
end
|
394
|
+
end
|
395
|
+
|
396
|
+
base_cmd = 'docker run -v $PWD:/code -w /code --link redis:redis prima_'
|
397
|
+
[
|
398
|
+
"docker-compose build web php",
|
399
|
+
"docker run -d --name redis redis:2.8",
|
400
|
+
"cd ../../ && docker run -e GIT_DIR=$PWD -v $PWD:/usr/app/src -w /usr/app/src/projects/prima blinkmobile/bower install --allow-root",
|
401
|
+
"#{base_cmd}web composer install -n",
|
402
|
+
"#{base_cmd}web npm install",
|
403
|
+
"#{base_cmd}php ./app/console -e=prod assets:install web",
|
404
|
+
"#{base_cmd}php ./app/console -e=prod fos:js-routing:dump",
|
405
|
+
"#{base_cmd}php ./app/console -e=prod cypress:ng-routing:dump",
|
406
|
+
"#{base_cmd}php ./app/console -e=prod bazinga:js-translation:dump web",
|
407
|
+
"#{base_cmd}web ./node_modules/.bin/brunch build -e staging",
|
408
|
+
"#{base_cmd}web composer dump-autoload --optimize --no-dev",
|
409
|
+
"#{base_cmd}compass compass compile --force -c web/compass/config_prod.rb web/compass/",
|
410
|
+
#"docker run -v $PWD:/code -w /code -e NODE_ENV=production prima_web ./node_modules/.bin/webpack --optimize-minimize",
|
411
|
+
"docker kill redis && docker rm redis"
|
412
|
+
].each do |cmd|
|
413
|
+
output "Eseguo #{cmd}".yellow
|
414
|
+
res = %x[ #{cmd} ]
|
415
|
+
if $?.exitstatus != 0
|
416
|
+
color = 'red'
|
417
|
+
else
|
418
|
+
color = 'green'
|
419
|
+
end
|
420
|
+
output res.send color
|
421
|
+
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
422
|
+
end
|
423
|
+
|
424
|
+
exec_step 'rsync -avd --exclude-from app/deploy/aws_docker/qa/.rsync-exclude-qa . /tmp/prima'
|
425
|
+
exec_step "rm -f #{@artifact_path}; cd /tmp/prima && zip -ryq #{@artifact_path} ."
|
426
|
+
|
427
|
+
upload_artifact(@artifact_path, "prima/#{revision}.zip")
|
428
|
+
|
429
|
+
Dir.chdir "../../"
|
430
|
+
end
|
431
|
+
|
432
|
+
def git_checkout_version(project, revision)
|
433
|
+
Dir.chdir "projects/#{project}"
|
434
|
+
exec_step "git checkout -- . && git clean -f -d && git checkout #{revision}"
|
435
|
+
Dir.chdir "../../"
|
436
|
+
end
|
363
437
|
|
364
|
-
|
438
|
+
def upload_artifact(source_path, destination_path)
|
439
|
+
output "Upload dell'artifact in corso (#{(File.size(source_path).to_f / 2**20).round(2)} MiB)\n".yellow
|
440
|
+
s3 = Aws::S3::Resource.new
|
441
|
+
obj = s3.bucket(@s3_bucket).object(destination_path)
|
442
|
+
obj.upload_file(source_path)
|
443
|
+
|
444
|
+
output "#{@s3_bucket}/#{destination_path} uploadato con successo!\n".green
|
445
|
+
end
|
365
446
|
|
447
|
+
def wait_for_stack_ready(stack_name)
|
448
|
+
ready = false
|
449
|
+
sleep_seconds = 10
|
450
|
+
output "Attendo che lo stack #{stack_name} finisca di essere inizializzato...\n".yellow
|
451
|
+
while !ready
|
452
|
+
ready = true if stack_ready?(stack_name)
|
366
453
|
seconds_elapsed = 0
|
367
454
|
while true
|
368
455
|
break if seconds_elapsed >= sleep_seconds
|
@@ -372,76 +459,139 @@ class Release
|
|
372
459
|
end
|
373
460
|
end
|
374
461
|
|
375
|
-
output "
|
462
|
+
output "\nStack #{stack_name} pronto!\n".green
|
376
463
|
end
|
377
464
|
|
378
|
-
def
|
379
|
-
|
380
|
-
|
381
|
-
})
|
382
|
-
|
383
|
-
resp = @ec2.describe_instances({instance_ids: [instance_id]})
|
384
|
-
|
385
|
-
resp.reservations[0].instances[0].public_ip_address
|
465
|
+
def stack_ready?(stack_name)
|
466
|
+
resp = @cf.describe_stacks({
|
467
|
+
stack_name: stack_name
|
468
|
+
})
|
469
|
+
['CREATE_COMPLETE', 'UPDATE_COMPLETE'].include? resp.stacks[0].stack_status
|
386
470
|
end
|
387
471
|
|
388
|
-
def
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
472
|
+
def create_asg_stack(stack_name)
|
473
|
+
stack_body = IO.read('cloudformation/stacks/asg/ecs-asg-allinone.json')
|
474
|
+
parameters = [
|
475
|
+
{
|
476
|
+
parameter_key: "Environment",
|
477
|
+
parameter_value: "qa"
|
478
|
+
},
|
479
|
+
{
|
480
|
+
parameter_key: "InstanceType",
|
481
|
+
parameter_value: "t2.large"
|
482
|
+
}
|
483
|
+
]
|
484
|
+
tags = []
|
485
|
+
create_stack(stack_name, stack_body, parameters, tags)
|
486
|
+
end
|
396
487
|
|
397
|
-
|
488
|
+
def import_dbs
|
489
|
+
resp = @ecs.run_task({
|
490
|
+
cluster: @qa_cluster,
|
491
|
+
task_definition: @import_db_task,
|
492
|
+
count: 1
|
493
|
+
})
|
494
|
+
output "Attendo che i DB vengano importati...\n".yellow
|
495
|
+
stopped_at = nil
|
496
|
+
while stopped_at.nil?
|
497
|
+
resp = @ecs.describe_tasks({
|
498
|
+
cluster: @qa_cluster,
|
499
|
+
tasks: [resp.tasks[0].task_arn]
|
500
|
+
})
|
501
|
+
stopped_at = resp.tasks[0].stopped_at
|
502
|
+
sleep_seconds = 10
|
503
|
+
seconds_elapsed = 0
|
504
|
+
while true && stopped_at.nil?
|
505
|
+
break if seconds_elapsed >= sleep_seconds
|
506
|
+
print '.'.yellow; STDOUT.flush
|
507
|
+
sleep 1
|
508
|
+
seconds_elapsed += 1
|
509
|
+
end
|
510
|
+
end
|
511
|
+
print "\n"
|
512
|
+
end
|
398
513
|
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
].each do |cmd|
|
408
|
-
output "Eseguo #{cmd}".yellow
|
409
|
-
res = %x[ #{cmd} ]
|
410
|
-
if $?.exitstatus != 0
|
411
|
-
color = 'red'
|
514
|
+
def stack_exists?(stack_name)
|
515
|
+
begin
|
516
|
+
res = @cf.describe_stacks({
|
517
|
+
stack_name: stack_name
|
518
|
+
})
|
519
|
+
rescue Aws::CloudFormation::Errors::ValidationError => e
|
520
|
+
if e.message.include? 'does not exist'
|
521
|
+
false
|
412
522
|
else
|
413
|
-
|
523
|
+
raise e
|
414
524
|
end
|
415
|
-
|
525
|
+
else
|
526
|
+
true
|
416
527
|
end
|
417
528
|
end
|
418
529
|
|
419
|
-
def
|
420
|
-
|
421
|
-
|
422
|
-
|
530
|
+
def create_stack(stack_name, stack_body, parameters = [], tags = [])
|
531
|
+
@cf.create_stack({
|
532
|
+
stack_name: stack_name,
|
533
|
+
template_body: stack_body,
|
534
|
+
parameters: parameters,
|
535
|
+
tags: tags,
|
536
|
+
capabilities: ["CAPABILITY_IAM"],
|
537
|
+
on_failure: "ROLLBACK"
|
423
538
|
})
|
424
|
-
|
539
|
+
output "La creazione dello stack #{stack_name} è stata avviata".green
|
425
540
|
end
|
426
541
|
|
427
|
-
def
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
542
|
+
def update_stack(stack_name, stack_body, parameters = [])
|
543
|
+
begin
|
544
|
+
@cf.update_stack({
|
545
|
+
stack_name: stack_name,
|
546
|
+
template_body: stack_body,
|
547
|
+
parameters: parameters,
|
548
|
+
capabilities: ["CAPABILITY_IAM"]
|
549
|
+
})
|
550
|
+
rescue Aws::CloudFormation::Errors::ValidationError => e
|
551
|
+
# if e.message.include? 'does not exist'
|
552
|
+
# false
|
553
|
+
# else
|
554
|
+
# raise e
|
555
|
+
# end
|
556
|
+
raise e
|
557
|
+
else
|
558
|
+
output "L'update dello stack #{stack_name} è stato avviato".green
|
440
559
|
end
|
441
|
-
|
442
|
-
|
560
|
+
end
|
561
|
+
|
562
|
+
def artifact_exists?(bucket, path)
|
563
|
+
resp = @s3.list_objects({
|
564
|
+
bucket: bucket,
|
565
|
+
max_keys: 1,
|
566
|
+
prefix: path
|
567
|
+
})
|
568
|
+
!resp.contents.empty?
|
569
|
+
end
|
570
|
+
|
571
|
+
def choose_branch_to_deploy(project_name)
|
572
|
+
Dir.chdir "projects/#{project_name}"
|
573
|
+
output "Recupero la lista dei branch del progetto #{project_name}..."
|
574
|
+
out = %x[ git fetch ]
|
575
|
+
branches = %x[ git for-each-ref --sort=-committerdate refs/remotes/ --format='%(refname) %(objectname)' | sed 's/refs\\/remotes\\/origin\\///g' ]
|
576
|
+
.split("\n").delete_if { |b| b.include?('HEAD') || b.include?('dev') }
|
577
|
+
|
578
|
+
branch_name = choose do |menu|
|
579
|
+
menu.prompt = "Scegli il branch di #{project_name} da deployare: ".cyan
|
580
|
+
menu.shell = true
|
581
|
+
|
582
|
+
branches.each do |branch|
|
583
|
+
|
584
|
+
title = @prima.reduce_size(branch, 100)
|
585
|
+
msg = "#{title}".light_blue
|
586
|
+
menu.choice(msg) { branch }
|
587
|
+
end
|
443
588
|
end
|
444
|
-
|
589
|
+
|
590
|
+
Dir.chdir "../../"
|
591
|
+
|
592
|
+
name = branch_name.split(' ').first
|
593
|
+
revision = branch_name.split(' ').last
|
594
|
+
{ name: name, revision: revision[0..14] }
|
445
595
|
end
|
446
596
|
|
447
597
|
end
|