fiver 0.0alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +7 -0
  2. data/.browserslistrc +1 -0
  3. data/.gitignore +57 -0
  4. data/.orchestration.yml +4 -0
  5. data/.rspec +3 -0
  6. data/.rspec_status +18 -0
  7. data/.rubocop.yml +10 -0
  8. data/.ruby-version +1 -0
  9. data/.travis.yml +6 -0
  10. data/Gemfile +36 -0
  11. data/Gemfile.lock +292 -0
  12. data/LICENSE +7 -0
  13. data/LICENSE.txt +21 -0
  14. data/Makefile +27 -0
  15. data/README.md +11 -0
  16. data/Rakefile +8 -0
  17. data/app/assets/config/manifest.js +2 -0
  18. data/app/assets/images/.keep +0 -0
  19. data/app/assets/stylesheets/application.css +15 -0
  20. data/app/channels/application_cable/channel.rb +6 -0
  21. data/app/channels/application_cable/connection.rb +6 -0
  22. data/app/controllers/application_controller.rb +4 -0
  23. data/app/controllers/concerns/.keep +0 -0
  24. data/app/helpers/application_helper.rb +5 -0
  25. data/app/javascript/channels/consumer.js +6 -0
  26. data/app/javascript/channels/index.js +5 -0
  27. data/app/javascript/packs/application.js +17 -0
  28. data/app/javascript/packs/hello_react.jsx +26 -0
  29. data/app/jobs/application_job.rb +9 -0
  30. data/app/mailers/application_mailer.rb +6 -0
  31. data/app/models/application_record.rb +6 -0
  32. data/app/models/concerns/.keep +0 -0
  33. data/app/views/layouts/application.html.erb +15 -0
  34. data/app/views/layouts/mailer.html.erb +13 -0
  35. data/app/views/layouts/mailer.text.erb +1 -0
  36. data/babel.config.js +87 -0
  37. data/bin/bundle +114 -0
  38. data/bin/console +14 -0
  39. data/bin/rails +9 -0
  40. data/bin/rake +9 -0
  41. data/bin/setup +8 -0
  42. data/bin/spring +17 -0
  43. data/bin/webpack +18 -0
  44. data/bin/webpack-dev-server +18 -0
  45. data/bin/yarn +11 -0
  46. data/config.ru +7 -0
  47. data/config/application.rb +18 -0
  48. data/config/boot.rb +6 -0
  49. data/config/cable.yml +10 -0
  50. data/config/credentials.yml.enc +1 -0
  51. data/config/database.yml +25 -0
  52. data/config/environment.rb +7 -0
  53. data/config/environments/development.rb +64 -0
  54. data/config/environments/production.rb +114 -0
  55. data/config/environments/test.rb +52 -0
  56. data/config/initializers/application_controller_renderer.rb +9 -0
  57. data/config/initializers/assets.rb +16 -0
  58. data/config/initializers/backtrace_silencers.rb +8 -0
  59. data/config/initializers/content_security_policy.rb +31 -0
  60. data/config/initializers/cookies_serializer.rb +7 -0
  61. data/config/initializers/filter_parameter_logging.rb +6 -0
  62. data/config/initializers/inflections.rb +17 -0
  63. data/config/initializers/mime_types.rb +5 -0
  64. data/config/initializers/wrap_parameters.rb +16 -0
  65. data/config/locales/en.yml +33 -0
  66. data/config/puma.rb +40 -0
  67. data/config/rabbitmq.yml +8 -0
  68. data/config/routes.rb +5 -0
  69. data/config/spring.rb +8 -0
  70. data/config/storage.yml +34 -0
  71. data/config/unicorn.rb +19 -0
  72. data/config/webpack/development.js +5 -0
  73. data/config/webpack/environment.js +3 -0
  74. data/config/webpack/production.js +5 -0
  75. data/config/webpack/test.js +5 -0
  76. data/config/webpacker.yml +97 -0
  77. data/db/schema.rb +15 -0
  78. data/db/seeds.rb +8 -0
  79. data/fiver.gemspec +26 -0
  80. data/lib/assets/.keep +0 -0
  81. data/lib/fiver.rb +12 -0
  82. data/lib/fiver/version.rb +5 -0
  83. data/lib/tasks/.keep +0 -0
  84. data/log/.keep +0 -0
  85. data/orchestration/Dockerfile +34 -0
  86. data/orchestration/Makefile +511 -0
  87. data/orchestration/docker-compose.development.yml +14 -0
  88. data/orchestration/docker-compose.production.yml +33 -0
  89. data/orchestration/docker-compose.test.yml +14 -0
  90. data/orchestration/entrypoint.sh +17 -0
  91. data/package.json +20 -0
  92. data/postcss.config.js +12 -0
  93. data/public/404.html +67 -0
  94. data/public/422.html +67 -0
  95. data/public/500.html +66 -0
  96. data/public/apple-touch-icon-precomposed.png +0 -0
  97. data/public/apple-touch-icon.png +0 -0
  98. data/public/favicon.ico +0 -0
  99. data/public/robots.txt +1 -0
  100. data/storage/.keep +0 -0
  101. data/tmp/.keep +0 -0
  102. data/tmp/pids/.keep +0 -0
  103. data/vendor/.keep +0 -0
  104. data/yarn.lock +7696 -0
  105. metadata +148 -0
data/lib/assets/.keep ADDED
File without changes
data/lib/fiver.rb ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ require 'fiver/version'
6
+ require 'fiver/virtual_host'
7
+ require 'fiver/queue'
8
+ require 'fiver/job'
9
+
10
+ module Fiver
11
+ class Error < StandardError; end
12
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fiver
4
+ VERSION = '0.0alpha'
5
+ end
data/lib/tasks/.keep ADDED
File without changes
data/log/.keep ADDED
File without changes
@@ -0,0 +1,34 @@
1
+ FROM ruby:2.7.1
2
+ ARG BUNDLE_BITBUCKET__ORG
3
+ ARG BUNDLE_GITHUB__COM
4
+ ARG GIT_COMMIT
5
+ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
6
+ && apt-get update \
7
+ && DEBIAN_FRONTEND=noninteractive apt-get install -y \
8
+ nodejs \
9
+ gosu \
10
+ sendmail \
11
+ && rm -rf /var/lib/apt/lists/* \
12
+ && gem install bundler \
13
+ && mkdir /app \
14
+ && curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash \
15
+ && . /root/.bashrc \
16
+ && nvm install 10.13.0 \
17
+ && npm config set user 0 \
18
+ && npm config set unsafe-perm true \
19
+ && npm install -g yarn
20
+ WORKDIR /app
21
+ COPY .build/Gemfile .build/Gemfile.lock ./
22
+ RUN bundle install --without development test --deployment
23
+ COPY .build/package.json .build/yarn.lock ./
24
+ RUN . /root/.bashrc ; yarn install
25
+ ADD .build/context.tar .
26
+ RUN . /root/.bashrc ; NODE_ENV=production RAILS_ENV=production yarn install && NODE_ENV=production RAILS_ENV=production SECRET_KEY_BASE=abc123 bundle exec rake assets:precompile
27
+ RUN echo "${GIT_COMMIT}" > /app/GIT_COMMIT
28
+ HEALTHCHECK --interval=30s \
29
+ --timeout=30s \
30
+ --start-period=5s \
31
+ --retries=3 \
32
+ CMD ["bundle","exec","rake","orchestration:healthcheck"]
33
+ ENTRYPOINT ["/app/orchestration/entrypoint.sh"]
34
+ CMD ["bundle","exec","unicorn","-c","config/unicorn.rb"]
@@ -0,0 +1,511 @@
1
+ ### Environment setup ###
2
+ SHELL:=/bin/bash
3
+
4
+ TERM ?= 'dumb'
5
+ pwd:=$(shell pwd)
6
+ ifdef mounted_orchestration
7
+ orchestration_dir=$(mounted_orchestration)
8
+ else
9
+ orchestration_dir=${pwd}/orchestration
10
+ endif
11
+
12
+ ifdef env_file
13
+ custom_env_file ?= 1
14
+ else
15
+ custom_env_file ?= 0
16
+ endif
17
+
18
+ ifneq (,$(wildcard ${pwd}/config/database.yml))
19
+ database_enabled = 1
20
+ else
21
+ database_enabled = 0
22
+ endif
23
+
24
+ make=$(MAKE) $1
25
+ orchestration_config_filename:=.orchestration.yml
26
+ orchestration_config:=${pwd}/${orchestration_config_filename}
27
+ print_error=printf '${red}\#${reset} '$1 | tee '${stderr}'
28
+ println_error=$(call print_error,$1'\n')
29
+ print=printf '${blue}\#${reset} '$1
30
+ println=$(call print,$1'\n')
31
+ printraw=printf $1
32
+ printrawln=$(call printraw,$1'\n')
33
+ stdout=${pwd}/log/orchestration.stdout.log
34
+ stderr=${pwd}/log/orchestration.stderr.log
35
+ log_path_length=$(shell echo "${stdout}" | wc -c)
36
+ ifndef verbose
37
+ log_tee:= 2>&1 | tee -a ${stdout}
38
+ log:= >>${stdout} 2>>${stderr}
39
+ progress_point:=perl -e 'while( my $$line = <STDIN> ) { printf("."); select()->flush(); }'
40
+ log_progress:= > >(tee -ai ${stdout} >&1 | ${progress_point}) 2> >(tee -ai ${stderr} 2>&1 | ${progress_point})
41
+ endif
42
+ red:=$(shell tput setaf 1)
43
+ green:=$(shell tput setaf 2)
44
+ yellow:=$(shell tput setaf 3)
45
+ blue:=$(shell tput setaf 4)
46
+ magenta:=$(shell tput setaf 5)
47
+ cyan:=$(shell tput setaf 6)
48
+ gray:=$(shell tput setaf 7)
49
+ reset:=$(shell tput sgr0)
50
+ tick=[${green}✓${reset}]
51
+ cross=[${red}✘${reset}]
52
+ warn=[${yellow}!${reset}]
53
+ hr=$(call println,"$1$(shell head -c ${log_path_length} < /dev/zero | tr '\0' '=')${reset}")
54
+ managed_env_tag:=\# -|- ORCHESTRATION
55
+ standard_env_path:=${pwd}/.env
56
+ backup_env_path:=${pwd}/.env.orchestration.backup
57
+ is_managed_env:=$$(test -f '${standard_env_path}' && tail -n 1 '${standard_env_path}') == "${managed_env_tag}"*
58
+ token:=$(shell cat /dev/urandom | LC_CTYPE=C tr -dc 'a-z0-9' | fold -w8 | head -n1)
59
+ back_up_env:=( \
60
+ [ ! -f '${standard_env_path}' ] \
61
+ || \
62
+ ( \
63
+ [ -f '${standard_env_path}' ] \
64
+ && cp '${standard_env_path}' '${backup_env_path}' \
65
+ ) \
66
+ )
67
+
68
+ replace_env:=( \
69
+ ( [ "${custom_env_file}" == "0" ] ) \
70
+ || \
71
+ ( \
72
+ [ "${custom_env_file}" == "1" ] \
73
+ && ${back_up_env} \
74
+ && cp ${env_file} '${standard_env_path}' \
75
+ && $(call printraw,'\n${managed_env_tag}') >> '${standard_env_path}' \
76
+ ) \
77
+ )
78
+
79
+ restore_env:=( \
80
+ ( \
81
+ [[ ! ${is_managed_env} ]] \
82
+ || [ ! -f '${backup_env_path}' ] \
83
+ ) \
84
+ || \
85
+ ( \
86
+ [ -f '${backup_env_path}' ] \
87
+ && [[ ${is_managed_env} ]] \
88
+ && mv '${backup_env_path}' '${standard_env_path}' \
89
+ ) \
90
+ )
91
+
92
+ key_chars:=[a-zA-Z0-9_]
93
+ censored:=**********
94
+ censor=s/\(^${key_chars}*$(1)${key_chars}*\)=\(.*\)$$/\1=${censored}/
95
+ censor_urls:=s|\([a-zA-Z0-9_+]\+://.*:\).*\(@.*\)$$|\1${censored}\2|
96
+ format_env:=sed '$(call censor,SECRET); \
97
+ $(call censor,TOKEN); \
98
+ $(call censor,PRIVATE); \
99
+ $(call censor,KEY); \
100
+ $(censor_urls); \
101
+ /^\s*$$/d; \
102
+ /^\s*\#/d; \
103
+ s/\(^[a-zA-Z0-9_]\+\)=/${blue}\1${reset}=/; \
104
+ s/^/ /; \
105
+ s/=\(.*\)$$/=${yellow}\1${reset}/' | \
106
+ sort
107
+
108
+ fail=( \
109
+ $(call printraw,' ${cross}') ; \
110
+ ${restore_env} ; \
111
+ $(call make,dump) ; \
112
+ echo ; \
113
+ $(call println,'Failed. ${cross}') ; \
114
+ exit 1 \
115
+ )
116
+
117
+
118
+ ifdef env_file
119
+ -include ${env_file}
120
+ else
121
+ ifneq (${env},test)
122
+ ifeq (,$(findstring test,$(MAKECMDGOALS)))
123
+ -include .env
124
+ endif
125
+ endif
126
+ endif
127
+
128
+ export
129
+
130
+ ifneq (,$(env))
131
+ # `env` set by current shell.
132
+ else ifneq (,$(RAILS_ENV))
133
+ env=$(RAILS_ENV)
134
+ else ifneq (,$(RACK_ENV))
135
+ env=$(RACK_ENV)
136
+ else
137
+ env=development
138
+ endif
139
+
140
+ DOCKER_TAG ?= latest
141
+
142
+ ifneq (,$(wildcard ./Gemfile))
143
+ rake=RACK_ENV=${env} RAILS_ENV=${env} bundle exec rake
144
+ else
145
+ rake=RACK_ENV=${env} RAILS_ENV=${env} rake
146
+ endif
147
+
148
+ ifneq (,$(wildcard ${env_file}))
149
+ rake_cmd:=${rake}
150
+ rake=. ${env_file} && ${rake_cmd}
151
+ endif
152
+
153
+ ifeq (,$(findstring serve,$(MAKECMDGOALS)))
154
+ ifeq (,$(findstring console,$(MAKECMDGOALS)))
155
+ ifeq (,$(findstring test,$(MAKECMDGOALS)))
156
+ docker_config:=$(shell RAILS_ENV=development bundle exec rake orchestration:config)
157
+ docker_organization=$(word 1,$(docker_config))
158
+ docker_repository=$(word 2,$(docker_config))
159
+ endif
160
+ endif
161
+ endif
162
+
163
+ ifeq (,$(project_name))
164
+ project_base = ${docker_repository}_${env}
165
+ else
166
+ project_base := $(project_name)
167
+ endif
168
+
169
+ ifeq (,$(findstring deploy,$(MAKECMDGOALS)))
170
+ sidecar_suffix := $(shell test -f ${orchestration_dir}/.sidecar && cat ${orchestration_dir}/.sidecar)
171
+ ifneq (,${sidecar_suffix})
172
+ sidecar := 1
173
+ endif
174
+
175
+ ifdef sidecar
176
+ # Set the variable to an empty string so that "#{sidecar-1234}" will
177
+ # evaluate to "1234" in port mappings.
178
+ sidecar_compose = sidecar=''
179
+ ifeq (,${sidecar_suffix})
180
+ sidecar_suffix := $(call token)
181
+ _ignore := $(shell echo ${sidecar_suffix} > ${orchestration_dir}/.sidecar)
182
+ endif
183
+
184
+ ifeq (,${sidecar_suffix})
185
+ $(warning Unable to generate project suffix; project name collisions may occur.)
186
+ endif
187
+ compose_project_name = ${project_base}_${sidecar_suffix}
188
+ else
189
+ compose_project_name = ${project_base}
190
+ endif
191
+ else
192
+ compose_project_name = ${project_base}
193
+ endif
194
+
195
+ compose_base=env -i \
196
+ PATH=$(PATH) \
197
+ HOST_UID=$(shell id -u) \
198
+ DOCKER_ORGANIZATION="${docker_organization}" \
199
+ DOCKER_REPOSITORY="${docker_repository}" \
200
+ COMPOSE_PROJECT_NAME="${compose_project_name}" \
201
+ ${sidecar_compose} \
202
+ docker-compose \
203
+ -f ${orchestration_dir}/docker-compose.${env}.yml
204
+
205
+ git_branch ?= $(if $(branch),$(branch),$(shell git rev-parse --abbrev-ref HEAD))
206
+ ifndef dev
207
+ git_version ?= $(shell git rev-parse --short --verify ${git_branch})
208
+ else
209
+ git_version = dev
210
+ endif
211
+
212
+ docker_image=${docker_organization}/${docker_repository}:${git_version}
213
+
214
+ compose=${compose_base}
215
+ random_str=cat /dev/urandom | LC_ALL=C tr -dc 'a-z' | head -c $1
216
+
217
+ ifneq (,$(wildcard ${orchestration_dir}/docker-compose.local.yml))
218
+ compose:=${compose} -f ${orchestration_dir}/docker-compose.local.yml
219
+ endif
220
+
221
+ all: build
222
+
223
+ ### Container management commands ###
224
+
225
+ .PHONY: start
226
+ ifndef network
227
+ start: network := ${compose_project_name}
228
+ endif
229
+ start: _create-log-directory _clean-logs
230
+ @$(call print,'${yellow}Starting ${cyan}${env}${yellow} containers${reset} ...')
231
+ ifeq (${env},$(filter ${env},test development))
232
+ @${compose} up --detach --force-recreate --renew-anon-volumes --remove-orphans ${services} ${log} || ${fail}
233
+ @[ -n '${sidecar}' ] && \
234
+ ( \
235
+ $(call printraw,' ${yellow}(joining dependency network ${green}${network}${yellow})${reset} ... ') ; \
236
+ docker network connect '${network}' '$(shell hostname)' ${log} \
237
+ || ( \
238
+ $(call println,'') ; \
239
+ $(call println,'${yellow}Warning${reset}: Unable to join network: "${yellow}${network}${reset}". Container will not be able to connect to dependency services.') ; \
240
+ $(call print,'You may need to delete "${yellow}orchestration/.sidecar${reset}" to disable sidecar mode if this file was added by mistake.\n...') ; \
241
+ ) \
242
+ ) \
243
+ || ( [ -z '${sidecar}' ] || ${fail} )
244
+ else
245
+ @${compose} up --detach --scale app=$${instances:-1} ${log} || ${fail}
246
+ endif
247
+ @$(call printrawln,' ${green}started${reset} ${tick}')
248
+ @$(call println,'${yellow}Waiting for services to become available${reset} ...')
249
+ @$(call make,wait) 2>${stderr} || ${fail}
250
+
251
+ .PHONY: start-database
252
+ start-database:
253
+ @$(call make,start services='database')
254
+
255
+ .PHONY: start-rabbitmq
256
+ start-rabbitmq:
257
+ @$(call make,start services='rabbitmq')
258
+
259
+ .PHONY: start-app
260
+ start-app:
261
+ @$(call make,start services='app')
262
+
263
+
264
+ .PHONY: stop
265
+ stop: network := ${compose_project_name}
266
+ stop:
267
+ @$(call print,'${yellow}Stopping ${cyan}${env}${yellow} containers${reset} ...')
268
+ @if docker ps --format "{{.ID}}" | grep -q $(shell hostname) ; \
269
+ then \
270
+ ( docker network disconnect ${network} $(shell hostname) ${log} || : ) \
271
+ && \
272
+ ( ${compose} down ${log} || ${fail} ) ; \
273
+ else \
274
+ ${compose} down ${log} || ${fail} ; \
275
+ fi
276
+ @$(call printrawln,' ${green}stopped${reset}. ${tick}')
277
+
278
+ .PHONY: logs
279
+ logs:
280
+ @${compose} logs -f
281
+
282
+ .PHONY: config
283
+ config:
284
+ @${compose} config
285
+
286
+ .PHONY: compose
287
+ compose:
288
+ @echo ${compose}
289
+
290
+ ### Development/Test Utility Commands
291
+
292
+ .PHONY: serve
293
+ serve: env_file ?= ./.env
294
+ serve: rails = RAILS_ENV='${env}' bundle exec rails server ${server}
295
+ serve:
296
+ @if [ -f "${env_file}" ] ; \
297
+ then ( \
298
+ $(call println,'${yellow}Environment${reset}: ${green}${env_file}${reset}') && \
299
+ cat '${env_file}' | ${format_env} && \
300
+ $(call printrawln,'') \
301
+ ) ; \
302
+ fi
303
+ ${rails}
304
+
305
+ .PHONY: console
306
+ console: env_file ?= ./.env
307
+ console: rails = RAILS_ENV='${env}' bundle exec rails
308
+ console:
309
+ @if [ -f "${env_file}" ] ; \
310
+ then ( \
311
+ $(call println,'${yellow}Environment${reset}: ${green}${env_file}${reset}') && \
312
+ cat '${env_file}' | ${format_env} && \
313
+ $(call printrawln,'') \
314
+ ) ; \
315
+ fi
316
+ ${rails} console
317
+
318
+ .PHONY: test-setup
319
+ test-setup: env := test
320
+ test-setup:
321
+ ifndef light
322
+ @$(call make,start env=test)
323
+ ifneq (,$(wildcard config/database.yml))
324
+ ${rake} db:create || :
325
+ ifneq (,$(wildcard db/structure.sql))
326
+ ${rake} db:structure:load
327
+ else ifneq (,$(wildcard db/schema.rb))
328
+ ${rake} db:schema:load
329
+ endif
330
+
331
+ ${rake} db:migrate
332
+ endif
333
+ endif
334
+
335
+ .PHONY: dump
336
+ dump:
337
+ ifndef verbose
338
+ @$(call println)
339
+ @$(call println,'${yellow}Captured${reset} ${green}stdout${reset} ${yellow}and${reset} ${red}stderr${reset} ${yellow}log data [${cyan}${env}${yellow}]${reset}:')
340
+ @$(call println)
341
+ @echo
342
+ @test -f '${stdout}' && ( \
343
+ $(call hr,${green}) ; \
344
+ $(call println,'${gray}${stdout}${reset}') ; \
345
+ $(call hr,${green}) ; \
346
+ echo ; cat '${stdout}' ; echo ; \
347
+ $(call hr,${green}) ; \
348
+ )
349
+
350
+ @test -f '${stdout}' && ( \
351
+ echo ; \
352
+ $(call hr,${red}) ; \
353
+ $(call println,'${gray}${stderr}${reset}') ; \
354
+ $(call hr,${red}) ; \
355
+ echo ; cat '${stderr}' ; echo ; \
356
+ $(call hr,${red}) ; \
357
+ )
358
+ endif
359
+ ifneq (,$(findstring deploy,$(MAKECMDGOALS)))
360
+ @echo ; \
361
+ $(call hr,${yellow}) ; \
362
+ $(call println,'${gray}docker-compose logs${reset}') ; \
363
+ $(call hr,${yellow}) ; \
364
+ echo
365
+ @${compose} logs
366
+ @echo ; \
367
+ $(call hr,${yellow})
368
+ endif
369
+ @$(NOOP)
370
+
371
+ .PHONY: image
372
+ image:
373
+ @echo ${docker_image}
374
+
375
+ ### Deployment utility commands ###
376
+
377
+ .PHONY: deploy
378
+ ifdef env_file
379
+ deploy: env_file_option = --env-file ${env_file}
380
+ endif
381
+ deploy: RAILS_ENV := ${env}
382
+ deploy: RACK_ENV := ${env}
383
+ deploy: DOCKER_TAG = ${git_version}
384
+ deploy: base_vars = DOCKER_ORGANIZATION=${docker_organization} DOCKER_REPOSITORY=${docker_repository} DOCKER_TAG=${git_version}
385
+ deploy: compose_deploy := ${base_vars} COMPOSE_PROJECT_NAME=${project_base} HOST_UID=$(shell id -u) docker-compose ${env_file_option} --project-name ${project_base} -f orchestration/docker-compose.production.yml
386
+ deploy: compose_config := ${compose_deploy} config
387
+ deploy: deploy_cmd := echo "$${config}" | ssh "${manager}" "/bin/bash -lc 'cat | docker stack deploy --prune --with-registry-auth -c - ${project_base}'"
388
+ deploy: out_of_sequence_error := rpc error: code = Unknown desc = update out of sequence
389
+ deploy: retry_message := ${yellow}Detected Docker RPC error: ${red}${out_of_sequence_error}${yellow}. Retrying in
390
+ deploy:
391
+ ifndef manager
392
+ @$(call println_error,'Missing `manager` parameter: `make deploy manager=swarm-manager.example.com`') ; exit 1
393
+ endif
394
+ @$(call println,'${yellow}Deploying ${green}${env} ${yellow}stack via ${green}${manager} ${yellow}as ${green}${project_base}${reset} ...') && \
395
+ ( \
396
+ $(call println,'${yellow}Deployment environment${reset}:') && \
397
+ ( test -f '${env_file}' && cat '${env_file}' | ${format_env} || : ) && \
398
+ $(call println,'') && \
399
+ $(call println,'${yellow}Application image${reset}: ${cyan}${docker_image}${reset}') && \
400
+ export config="$$(${compose_config} 2>${stderr})" ; \
401
+ config_exit_code=$$? ; \
402
+ if [[ "$${config_exit_code}" != "0" ]]; then exit ${config_exit_code}; fi ; \
403
+ output="$$(${deploy_cmd} | tee)" ; \
404
+ deploy_exit_code=$$? ; \
405
+ if [[ "$${deploy_exit_code}" == 0 ]] ; then exit 0 ; fi ; \
406
+ if ! echo "$${output}" | grep -q '${out_of_sequence_error}' ; then exit ${deploy_exit_code} ; fi ; \
407
+ retry_in="$$(( 10 + RANDOM % 50 ))" ; \
408
+ echo "${retry_message} ${green}$${retry_in} ${yellow}seconds.${reset}" ; \
409
+ sleep "$${retry_in}" ; \
410
+ ${deploy_cmd} \
411
+ ) \
412
+ || ${fail}
413
+
414
+ @$(call println,'${yellow}Deployment${reset} ${green}complete${reset}. ${tick}')
415
+
416
+ .PHONY: rollback
417
+ ifndef service
418
+ rollback: service = app
419
+ endif
420
+ rollback:
421
+ ifndef manager
422
+ @$(call println_error,'Missing `manager` parameter: `make deploy manager=swarm-manager.example.com`') ; exit 1
423
+ endif
424
+ @$(call println,'${yellow}Rolling back${reset} ${green}${compose_project_name}_${service}${reset} ${yellow}via${reset} ${green}${manager}${reset} ...')
425
+ @ssh "${manager}" 'docker service rollback --detach "${compose_project_name}_${service}"' ${log} || ${fail}
426
+ @$(call println,'${yellow}Rollback request${reset} ${green}complete${reset}. ${tick}')
427
+
428
+ ### Service healthcheck commands ###
429
+
430
+ .PHONY: wait
431
+ wait:
432
+ @${rake} orchestration:wait
433
+ @$(call println,'${yellow}All services${reset} ${green}ready${reset}. ${tick}')
434
+
435
+ ## Generic Listener healthcheck for TCP services ##
436
+
437
+ wait-listener:
438
+ @${rake} orchestration:listener:wait service=${service} sidecar=${sidecar}
439
+
440
+ ### Docker build commands ###
441
+
442
+ .PHONY: build
443
+ build: build_dir = ${orchestration_dir}/.build
444
+ build: context = ${build_dir}/context.tar
445
+ build: _create-log-directory check-local-changes
446
+ @$(call print,'${yellow}Preparing build context from${reset} ${cyan}${git_branch}:${git_version}${reset} ... ')
447
+ @mkdir -p ${orchestration_dir}/.build ${log} || ${fail}
448
+ ifndef dev
449
+ @git show ${git_branch}:./Gemfile > ${orchestration_dir}/.build/Gemfile 2>${stderr} || ${fail}
450
+ @git show ${git_branch}:./Gemfile.lock > ${orchestration_dir}/.build/Gemfile.lock 2>${stderr} || ${fail}
451
+ @git show ${git_branch}:./package.json > ${orchestration_dir}/.build/package.json 2>${stderr} || ${fail}
452
+ @git show ${git_branch}:./yarn.lock > ${orchestration_dir}/.build/yarn.lock 2>${stderr} || ${fail}
453
+ @git archive --format 'tar' -o '${context}' '${git_branch}' ${log} || ${fail}
454
+ else
455
+ @tar -cvf '${context}' . ${log} || ${fail}
456
+ endif
457
+ @$(call printrawln,'${green}complete.${reset} ${tick}')
458
+ ifdef include
459
+ @$(call print,'${yellow}Including files from:${reset} ${cyan}${include}${reset} ...')
460
+ @(while read line; do \
461
+ export line; \
462
+ include_dir="${build_dir}/$$(dirname "$${line}")/" && \
463
+ mkdir -p "$${include_dir}" && cp "$${line}" "$${include_dir}" \
464
+ && (cd '${orchestration_dir}/.build/' && tar rf 'context.tar' "$${line}"); \
465
+ done < '${include}') ${log} || ${fail}
466
+ @$(call printrawln,' ${green}complete.${reset} ${tick}')
467
+ endif
468
+ ifdef sidecar
469
+ # Assume we are in a line-buffered environment (e.g. Jenkins)
470
+ @$(call println,'${yellow}Building image${reset} ...')
471
+ else
472
+ @$(call print,'${yellow}Building image${reset} ...')
473
+ endif
474
+ @docker build \
475
+ --build-arg BUNDLE_GITHUB__COM \
476
+ --build-arg BUNDLE_BITBUCKET__ORG \
477
+ --build-arg GIT_COMMIT='${git_version}' \
478
+ -t ${docker_organization}/${docker_repository} \
479
+ -t ${docker_organization}/${docker_repository}:${git_version} \
480
+ ${orchestration_dir}/ ${log_progress} || ${fail}
481
+ @$(call printrawln,' ${green}complete${reset}. ${tick}')
482
+ @$(call println,'[${green}tag${reset}] ${cyan}${docker_organization}/${docker_repository}${reset}')
483
+ @$(call println,'[${green}tag${reset}] ${cyan}${docker_organization}/${docker_repository}:${git_version}${reset}')
484
+
485
+ .PHONY: push
486
+ push: _create-log-directory
487
+ @$(call print,'${yellow}Pushing${reset} ${cyan}${docker_image}${reset} ...')
488
+ @docker push ${docker_image} ${log_progress} || ${fail}
489
+ @$(call printrawln,' ${green}complete${reset}. ${tick}')
490
+
491
+ .PHONY: check-local-changes
492
+ check-local-changes:
493
+ ifndef dev
494
+ @if [[ ! -z "$$(git status --porcelain)" ]] ; \
495
+ then \
496
+ $(call println,'${red}You have uncommitted changes which will not be included in your build:${reset}') ; \
497
+ git status --porcelain ; \
498
+ $(call println,'${yellow}Use ${cyan}make build dev=1${reset} ${yellow}to include these files.${reset}\n') ; \
499
+ fi
500
+ endif
501
+
502
+ ### Internal Commands ###
503
+ #
504
+ .PHONY: _clean-logs
505
+ _clean-logs:
506
+ @rm -f '${stdout}' '${stderr}'
507
+ @touch '${stdout}' '${stderr}'
508
+
509
+ .PHONY: _create-log-directory
510
+ _create-log-directory:
511
+ @mkdir -p log