shipitron 0.3.5 → 0.4.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 +5 -5
- data/Dockerfile +2 -2
- data/Dockerfile.release +2 -2
- data/README.md +6 -5
- data/lib/shipitron/cli.rb +5 -5
- data/lib/shipitron/client/deploy_application.rb +3 -0
- data/lib/shipitron/client/fetch_clusters.rb +43 -0
- data/lib/shipitron/client/load_application_config.rb +2 -1
- data/lib/shipitron/client/load_templates.rb +4 -3
- data/lib/shipitron/client/run_ecs_tasks.rb +79 -54
- data/lib/shipitron/ecs_client.rb +1 -1
- data/lib/shipitron/server/deploy_application.rb +2 -1
- data/lib/shipitron/server/docker/configure.rb +5 -1
- data/lib/shipitron/server/docker/push_image.rb +9 -4
- data/lib/shipitron/server/git/configure.rb +10 -2
- data/lib/shipitron/server/git/update_cache.rb +1 -1
- data/lib/shipitron/server/run_post_build.rb +5 -5
- data/lib/shipitron/server/transform_cli_args.rb +4 -2
- data/lib/shipitron/server/update_deploy_ref.rb +6 -1
- data/lib/shipitron/server/update_ecs_services.rb +46 -45
- data/lib/shipitron/version.rb +1 -1
- data/shipitron.gemspec +15 -13
- metadata +59 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1b1404f46280ca67a501c2c249f955b266d028466357edb5332c8572ad487e0b
|
4
|
+
data.tar.gz: 93d96a64b5aec13d99c3927b593b5c564429ad34f5d7e9aaf162ef9499d52d2f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5cfd2a66affc37f96d87d96e1311a06cb7deaea52f98a591962772afbe5ef25038cd5a62b718576be367c22d24e15a00261f61ee4fa98620e3790faece8588b
|
7
|
+
data.tar.gz: d5c4703312aeb1a64b61544c5a1f6ad5a533e60def6e8b29c09726fce89b974a6dfe939769ee5268f4501cd628c4271148cbe179ec60914767ac72073cf6e738
|
data/Dockerfile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
FROM ruby:2.
|
1
|
+
FROM ruby:2.5.0-alpine3.7 as cache
|
2
2
|
COPY cache/ /tmp/
|
3
3
|
RUN cd /usr/local/bundle && \
|
4
4
|
([ -f /tmp/bundler-data.tar.gz ] && \
|
5
5
|
tar -zxf /tmp/bundler-data.tar.gz && \
|
6
6
|
rm /tmp/bundler-data.tar.gz) || true
|
7
7
|
|
8
|
-
FROM ruby:2.
|
8
|
+
FROM ruby:2.5.0-alpine3.7
|
9
9
|
MAINTAINER Ryan Schlesinger <ryan@outstand.com>
|
10
10
|
|
11
11
|
RUN addgroup -S shipitron && \
|
data/Dockerfile.release
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
FROM ruby:2.
|
1
|
+
FROM ruby:2.5.0-alpine3.7
|
2
2
|
MAINTAINER Ryan Schlesinger <ryan@outstand.com>
|
3
3
|
|
4
4
|
RUN addgroup -S shipitron && \
|
@@ -40,7 +40,7 @@ RUN apk add --no-cache \
|
|
40
40
|
|
41
41
|
WORKDIR /app
|
42
42
|
|
43
|
-
ENV SHIPITRON_VERSION=0.
|
43
|
+
ENV SHIPITRON_VERSION=0.4.0
|
44
44
|
|
45
45
|
RUN gem install shipitron -v ${SHIPITRON_VERSION} && \
|
46
46
|
mkdir -p /home/shipitron/.ssh && \
|
data/README.md
CHANGED
@@ -15,11 +15,7 @@ applications:
|
|
15
15
|
- ecs_task: dummy-app
|
16
16
|
container_name: dummy-app
|
17
17
|
command: echo postbuild
|
18
|
-
|
19
|
-
- name: us-east-1-prod-blue
|
20
|
-
region: us-east-1
|
21
|
-
- name: us-east-1-prod-green
|
22
|
-
region: us-east-1
|
18
|
+
cluster_discovery: _ecs-prod._tcp.example.com
|
23
19
|
shipitron_task: shipitron
|
24
20
|
ecs_task_defs:
|
25
21
|
- dummy-app
|
@@ -44,6 +40,11 @@ applications:
|
|
44
40
|
- `docker run -it --rm -v $(pwd):/shipitron -v $APP_PATH:/app outstand/shipitron:dev deploy <app> --simulate` to get the arguments for `server_deploy` below
|
45
41
|
- `docker run -it --rm --dns 10.10.10.2 -v $(pwd):/shipitron -v $APP_PATH:/app -v /bin/docker:/bin/docker -v /var/run/docker.sock:/var/run/docker.sock -v shipitron_fog:/fog -e FOG_LOCAL=true -e CONSUL_HOST=consul outstand/shipitron:dev server_deploy --name dummy-app --repository git@github.com:outstand/dummy-app --bucket outstand-shipitron --image-name outstand/dummy-app --region us-east-1 --cluster-name us-east-1-prod-blue --ecs-task-defs dummy-app --ecs-services dummy-app --build-script shipitron/build.sh --post-builds 'ecs_task:dummy-app,container_name:dummy-app,command:echo postbuild' --ecs-task-def-templates LS0tCmZhbWlseTogZHVtbXktYXBwCmNvbnRhaW5lcl9kZWZpbml0aW9uczoKICAtIG5hbWU6IGR1bW15LWFwcAogICAgaW1hZ2U6IG91dHN0YW5kL2R1bW15LWFwcDp7e3RhZ319CiAgICBtZW1vcnk6IDEyOAogICAgZXNzZW50aWFsOiB0cnVlCiAgICBwb3J0X21hcHBpbmdzOgogICAgICAtIGNvbnRhaW5lcl9wb3J0OiA4MAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gbmFtZTogU0VSVklDRV84MF9OQU1FCiAgICAgICAgdmFsdWU6IGR1bW15Cg== --ecs-service-templates LS0tCmNsdXN0ZXI6IHt7Y2x1c3Rlcn19CnNlcnZpY2VfbmFtZTogZHVtbXktYXBwCnRhc2tfZGVmaW5pdGlvbjogZHVtbXktYXBwe3tyZXZpc2lvbn19CmRlc2lyZWRfY291bnQ6IHt7Y291bnR9fQojcm9sZToge3tyb2xlfX0KZGVwbG95bWVudF9jb25maWd1cmF0aW9uOgogIG1heGltdW1fcGVyY2VudDogMjAwCiAgbWluaW11bV9oZWFsdGh5X3BlcmNlbnQ6IDUwCg== --debug` to run server side (dummy-app is an example)
|
46
42
|
|
43
|
+
Running a dev version in production:
|
44
|
+
- `docker push outstand/shipitron:dev`
|
45
|
+
- Update config to use `shipitron_task: shipitron-dev`
|
46
|
+
- `docker run -it --rm -v $(pwd):/shipitron -v $APP_PATH:/app outstand/shipitron:dev deploy <app> --debug`
|
47
|
+
|
47
48
|
To release a new version:
|
48
49
|
- Update the version number in `version.rb` and `Dockerfile.release` and commit the result.
|
49
50
|
- `./build_dev.sh`
|
data/lib/shipitron/cli.rb
CHANGED
@@ -12,8 +12,6 @@ module Shipitron
|
|
12
12
|
desc 'deploy <app>', 'Deploys the app'
|
13
13
|
option :config_file, default: 'shipitron/config.yml'
|
14
14
|
option :secrets_file, default: 'shipitron/secrets.yml'
|
15
|
-
option :ember, type: :boolean, default: false
|
16
|
-
option :ember_only, type: :boolean, default: false
|
17
15
|
option :debug, type: :boolean, default: false
|
18
16
|
option :simulate, type: :boolean, default: false
|
19
17
|
def deploy(app)
|
@@ -42,8 +40,9 @@ module Shipitron
|
|
42
40
|
option :repository_branch, default: 'master'
|
43
41
|
option :bucket, required: true
|
44
42
|
option :image_name, required: true
|
43
|
+
option :named_tag, default: 'latest'
|
45
44
|
option :region, required: true
|
46
|
-
option :
|
45
|
+
option :clusters, type: :array, required: true
|
47
46
|
option :ecs_task_defs, type: :array, required: true
|
48
47
|
option :ecs_task_def_templates, type: :array, default: []
|
49
48
|
option :ecs_services, type: :array, default: []
|
@@ -64,8 +63,9 @@ module Shipitron
|
|
64
63
|
repository_branch: options[:repository_branch],
|
65
64
|
s3_cache_bucket: options[:bucket],
|
66
65
|
image_name: options[:image_name],
|
66
|
+
named_tag: options[:named_tag],
|
67
67
|
region: options[:region],
|
68
|
-
|
68
|
+
clusters: options[:clusters],
|
69
69
|
ecs_task_defs: options[:ecs_task_defs],
|
70
70
|
ecs_task_def_templates: options[:ecs_task_def_templates],
|
71
71
|
ecs_services: options[:ecs_services],
|
@@ -90,7 +90,7 @@ module Shipitron
|
|
90
90
|
desc 'bootstrap <app>', 'Bootstrap ECS task definitions and services'
|
91
91
|
option :region, required: true
|
92
92
|
option :cluster_name, required: true
|
93
|
-
option :service_count, type: :numeric, default:
|
93
|
+
option :service_count, type: :numeric, default: 0
|
94
94
|
option :task_def_dir, default: 'shipitron/ecs_task_defs'
|
95
95
|
option :service_dir, default: 'shipitron/ecs_services'
|
96
96
|
option :secrets_file, default: 'shipitron/secrets.yml'
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'shipitron'
|
2
2
|
require 'shipitron/client/load_application_config'
|
3
3
|
require 'shipitron/client/load_templates'
|
4
|
+
require 'shipitron/client/fetch_clusters'
|
4
5
|
require 'shipitron/client/ensure_deploy_not_running'
|
5
6
|
require 'shipitron/client/run_ecs_tasks'
|
6
7
|
|
@@ -11,10 +12,12 @@ module Shipitron
|
|
11
12
|
include Interactor::Organizer
|
12
13
|
|
13
14
|
required :application
|
15
|
+
optional :simulate
|
14
16
|
|
15
17
|
organize [
|
16
18
|
LoadApplicationConfig,
|
17
19
|
LoadTemplates,
|
20
|
+
FetchClusters,
|
18
21
|
EnsureDeployNotRunning,
|
19
22
|
RunEcsTasks
|
20
23
|
]
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'shipitron'
|
2
|
+
require 'resolv'
|
3
|
+
|
4
|
+
module Shipitron
|
5
|
+
module Client
|
6
|
+
class FetchClusters
|
7
|
+
include Metaractor
|
8
|
+
|
9
|
+
required :cluster_discovery
|
10
|
+
|
11
|
+
def call
|
12
|
+
resources = dns_resources.sort! do |a,b|
|
13
|
+
(a.priority <=> b.priority).yield_self do |prio|
|
14
|
+
if prio == 0
|
15
|
+
b.weight <=> a.weight
|
16
|
+
else
|
17
|
+
prio
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context.clusters = resources.map do |r|
|
23
|
+
Smash.new(
|
24
|
+
name: r.target[0].to_s,
|
25
|
+
region: r.target[1].to_s
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
Logger.debug "Clusters: #{context.clusters.inspect}"
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
def dns_resources
|
34
|
+
Resolv::DNS.open do |dns|
|
35
|
+
dns.getresources(
|
36
|
+
context.cluster_discovery,
|
37
|
+
Resolv::DNS::Resource::IN::SRV
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -13,6 +13,7 @@ module Shipitron
|
|
13
13
|
context.repository_branch = config.repository_branch
|
14
14
|
context.s3_cache_bucket = config.cache_bucket
|
15
15
|
context.image_name = config.image_name
|
16
|
+
context.named_tag = config.named_tag
|
16
17
|
context.build_script = config.build_script
|
17
18
|
context.post_builds = begin
|
18
19
|
if config.post_builds.nil?
|
@@ -21,7 +22,7 @@ module Shipitron
|
|
21
22
|
config.post_builds.map {|pb| PostBuild.new(pb) }
|
22
23
|
end
|
23
24
|
end
|
24
|
-
context.
|
25
|
+
context.cluster_discovery = config.cluster_discovery
|
25
26
|
context.shipitron_task = config.shipitron_task
|
26
27
|
context.ecs_task_defs = config.ecs_task_defs
|
27
28
|
context.ecs_services = config.ecs_services
|
@@ -23,7 +23,7 @@ module Shipitron
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def load_templates(dir)
|
26
|
-
return
|
26
|
+
return {} if dir.nil?
|
27
27
|
|
28
28
|
search_path = Pathname.new(dir)
|
29
29
|
unless search_path.directory?
|
@@ -32,11 +32,12 @@ module Shipitron
|
|
32
32
|
)
|
33
33
|
end
|
34
34
|
|
35
|
-
templates =
|
35
|
+
templates = {}
|
36
36
|
search_path.find do |path|
|
37
37
|
next if path.directory?
|
38
|
+
next if path.extname != '.yml'
|
38
39
|
|
39
|
-
templates
|
40
|
+
templates[path.basename('.yml').to_s] = path.read
|
40
41
|
end
|
41
42
|
|
42
43
|
Logger.debug "Templates loaded: #{templates.inspect}"
|
@@ -2,6 +2,8 @@ require 'shipitron'
|
|
2
2
|
require 'shipitron/ecs_client'
|
3
3
|
require 'shellwords'
|
4
4
|
require 'base64'
|
5
|
+
require 'tty-table'
|
6
|
+
require 'pastel'
|
5
7
|
|
6
8
|
module Shipitron
|
7
9
|
module Client
|
@@ -15,6 +17,7 @@ module Shipitron
|
|
15
17
|
required :repository_url
|
16
18
|
required :s3_cache_bucket
|
17
19
|
required :image_name
|
20
|
+
required :named_tag
|
18
21
|
required :ecs_task_defs
|
19
22
|
optional :ecs_task_def_templates
|
20
23
|
optional :ecs_services
|
@@ -26,48 +29,63 @@ module Shipitron
|
|
26
29
|
|
27
30
|
before do
|
28
31
|
context.post_builds ||= []
|
29
|
-
context.ecs_task_def_templates ||=
|
32
|
+
context.ecs_task_def_templates ||= {}
|
30
33
|
context.ecs_services ||= []
|
31
|
-
context.ecs_service_templates ||=
|
34
|
+
context.ecs_service_templates ||= {}
|
32
35
|
end
|
33
36
|
|
34
37
|
def call
|
35
38
|
Logger.info "Skipping ECS run_task calls due to --simulate" if simulate?
|
36
39
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
40
|
+
Logger.info "Deploying to:"
|
41
|
+
pastel = Pastel.new
|
42
|
+
table = TTY::Table.new do |t|
|
43
|
+
clusters.each_with_index do |cluster, i|
|
44
|
+
if i == 0
|
45
|
+
t << [pastel.yellow('*'), cluster.name, cluster.region, '[' + pastel.green('shipitron') + ']']
|
46
|
+
else
|
47
|
+
t << ['', cluster.name, cluster.region, '']
|
42
48
|
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
table.render.each_line do |line|
|
52
|
+
Logger.info line.chomp
|
53
|
+
end
|
43
54
|
|
44
|
-
|
45
|
-
cluster: cluster.name,
|
46
|
-
task_definition: shipitron_task,
|
47
|
-
overrides: {
|
48
|
-
container_overrides: [
|
49
|
-
{
|
50
|
-
name: 'shipitron',
|
51
|
-
command: command_args(cluster)
|
52
|
-
}
|
53
|
-
]
|
54
|
-
},
|
55
|
-
count: 1,
|
56
|
-
started_by: 'shipitron'
|
57
|
-
)
|
55
|
+
cluster = clusters.first
|
58
56
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
57
|
+
begin
|
58
|
+
if simulate?
|
59
|
+
command_args(cluster)
|
60
|
+
return
|
61
|
+
end
|
64
62
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
63
|
+
response = ecs_client(region: cluster.region).run_task(
|
64
|
+
cluster: cluster.name,
|
65
|
+
task_definition: shipitron_task,
|
66
|
+
overrides: {
|
67
|
+
container_overrides: [
|
68
|
+
{
|
69
|
+
name: 'shipitron',
|
70
|
+
command: command_args(cluster)
|
71
|
+
}
|
72
|
+
]
|
73
|
+
},
|
74
|
+
count: 1,
|
75
|
+
started_by: 'shipitron'
|
76
|
+
)
|
77
|
+
|
78
|
+
if !response.failures.empty?
|
79
|
+
response.failures.each do |failure|
|
80
|
+
fail_with_error! message: "ECS run_task failure: #{failure.arn}: #{failure.reason}"
|
81
|
+
end
|
70
82
|
end
|
83
|
+
|
84
|
+
rescue Aws::ECS::Errors::ServiceError => e
|
85
|
+
fail_with_errors!(messages: [
|
86
|
+
"Error: #{e.message}",
|
87
|
+
e.backtrace.join("\n")
|
88
|
+
])
|
71
89
|
end
|
72
90
|
end
|
73
91
|
|
@@ -84,59 +102,66 @@ module Shipitron
|
|
84
102
|
context.shipitron_task
|
85
103
|
end
|
86
104
|
|
87
|
-
def escape(str)
|
88
|
-
Shellwords.escape(str)
|
89
|
-
end
|
90
|
-
|
91
|
-
def escaped(sym)
|
92
|
-
escape(context[sym])
|
93
|
-
end
|
94
|
-
|
95
105
|
def command_args(cluster)
|
96
106
|
[
|
97
107
|
'server_deploy',
|
98
|
-
'--name',
|
99
|
-
'--repository',
|
100
|
-
'--bucket',
|
101
|
-
'--image-name',
|
102
|
-
'--
|
103
|
-
'--
|
108
|
+
'--name', context.application,
|
109
|
+
'--repository', context.repository_url,
|
110
|
+
'--bucket', context.s3_cache_bucket,
|
111
|
+
'--image-name', context.image_name,
|
112
|
+
'--named-tag', context.named_tag,
|
113
|
+
'--region', cluster.region,
|
104
114
|
].tap do |ary|
|
115
|
+
ary << '--clusters'
|
116
|
+
ary.concat(context.clusters.map(&:name))
|
117
|
+
|
105
118
|
ary << '--ecs-task-defs'
|
106
|
-
ary.concat(context.ecs_task_defs
|
119
|
+
ary.concat(context.ecs_task_defs)
|
107
120
|
|
108
121
|
unless context.ecs_services.empty?
|
109
122
|
ary << '--ecs-services'
|
110
|
-
ary.concat(context.ecs_services
|
123
|
+
ary.concat(context.ecs_services)
|
111
124
|
end
|
112
125
|
|
113
126
|
if context.build_script != nil
|
114
|
-
ary.concat ['--build-script',
|
127
|
+
ary.concat ['--build-script', context.build_script]
|
115
128
|
end
|
116
129
|
|
117
130
|
if !context.post_builds.empty?
|
118
131
|
ary << '--post-builds'
|
119
|
-
ary.concat(context.post_builds.map(&:to_s)
|
132
|
+
ary.concat(context.post_builds.map(&:to_s))
|
120
133
|
end
|
121
134
|
|
122
135
|
if !context.ecs_task_def_templates.empty?
|
123
136
|
ary << '--ecs-task-def-templates'
|
124
|
-
ary.concat(
|
137
|
+
ary.concat(
|
138
|
+
context.ecs_task_def_templates.map do |name, data|
|
139
|
+
if context.ecs_task_defs.include?(name)
|
140
|
+
Base64.urlsafe_encode64(data)
|
141
|
+
end
|
142
|
+
end.compact
|
143
|
+
)
|
125
144
|
end
|
126
145
|
|
127
146
|
if !context.ecs_service_templates.empty?
|
128
147
|
ary << '--ecs-service-templates'
|
129
|
-
ary.concat(
|
148
|
+
ary.concat(
|
149
|
+
context.ecs_service_templates.map do |name, data|
|
150
|
+
if context.ecs_services.include?(name)
|
151
|
+
Base64.urlsafe_encode64(data)
|
152
|
+
end
|
153
|
+
end.compact
|
154
|
+
)
|
130
155
|
end
|
131
156
|
|
132
157
|
unless context.repository_branch.nil?
|
133
|
-
ary.concat ['--repository-branch',
|
158
|
+
ary.concat ['--repository-branch', context.repository_branch]
|
134
159
|
end
|
135
160
|
|
136
161
|
if simulate?
|
137
|
-
Logger.info "server_deploy command: #{ary.
|
162
|
+
Logger.info "server_deploy command: #{ary.shelljoin}"
|
138
163
|
else
|
139
|
-
Logger.debug "server_deploy command: #{ary.
|
164
|
+
Logger.debug "server_deploy command: #{ary.shelljoin}"
|
140
165
|
end
|
141
166
|
end
|
142
167
|
end
|
data/lib/shipitron/ecs_client.rb
CHANGED
@@ -20,8 +20,9 @@ module Shipitron
|
|
20
20
|
required :repository_url
|
21
21
|
required :s3_cache_bucket
|
22
22
|
required :docker_image
|
23
|
+
required :named_tag
|
23
24
|
required :region
|
24
|
-
required :
|
25
|
+
required :clusters
|
25
26
|
required :ecs_task_defs
|
26
27
|
optional :ecs_task_def_templates
|
27
28
|
optional :ecs_services
|
@@ -15,7 +15,11 @@ module Shipitron
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def call
|
18
|
-
docker_auth =
|
18
|
+
docker_auth = begin
|
19
|
+
key = fetch_key(key: "shipitron/#{application}/docker_auth")
|
20
|
+
key = fetch_key!(key: 'shipitron/docker_auth') if key.nil?
|
21
|
+
key
|
22
|
+
end
|
19
23
|
auth_file = Pathname.new('/home/shipitron/.docker/config.json')
|
20
24
|
auth_file.parent.mkpath
|
21
25
|
auth_file.open('wb') do |file|
|
@@ -7,11 +7,12 @@ module Shipitron
|
|
7
7
|
include Metaractor
|
8
8
|
|
9
9
|
required :docker_image
|
10
|
+
required :named_tag
|
10
11
|
|
11
12
|
def call
|
12
|
-
Logger.info "Pushing docker image #{docker_image} and #{docker_image.name_with_tag(
|
13
|
+
Logger.info "Pushing docker image #{docker_image} and #{docker_image.name_with_tag(named_tag)}"
|
13
14
|
|
14
|
-
Logger.info `docker tag #{docker_image} #{docker_image.name_with_tag(
|
15
|
+
Logger.info `docker tag #{docker_image} #{docker_image.name_with_tag(named_tag)}`
|
15
16
|
if $? != 0
|
16
17
|
fail_with_error!(message: 'Docker tag failed.')
|
17
18
|
end
|
@@ -21,9 +22,9 @@ module Shipitron
|
|
21
22
|
fail_with_error!(message: 'Docker push failed.')
|
22
23
|
end
|
23
24
|
|
24
|
-
Logger.info `docker push #{docker_image.name_with_tag(
|
25
|
+
Logger.info `docker push #{docker_image.name_with_tag(named_tag)}`
|
25
26
|
if $? != 0
|
26
|
-
fail_with_error!(message:
|
27
|
+
fail_with_error!(message: "Docker push (#{named_tag}) failed.")
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
@@ -31,6 +32,10 @@ module Shipitron
|
|
31
32
|
def docker_image
|
32
33
|
context.docker_image
|
33
34
|
end
|
35
|
+
|
36
|
+
def named_tag
|
37
|
+
context.named_tag
|
38
|
+
end
|
34
39
|
end
|
35
40
|
end
|
36
41
|
end
|
@@ -17,12 +17,20 @@ module Shipitron
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def call
|
20
|
-
host_key =
|
20
|
+
host_key = begin
|
21
|
+
key = fetch_key(key: "shipitron/#{application}/git_host_key")
|
22
|
+
key = fetch_key!(key: 'shipitron/git_host_key') if key.nil?
|
23
|
+
key
|
24
|
+
end
|
21
25
|
Pathname.new('/home/shipitron/.ssh/known_hosts').open('a') do |file|
|
22
26
|
file.puts(host_key.to_s)
|
23
27
|
end
|
24
28
|
|
25
|
-
deploy_key =
|
29
|
+
deploy_key = begin
|
30
|
+
key = fetch_key(key: "shipitron/#{application}/git_deploy_key")
|
31
|
+
key = fetch_key!(key: 'shipitron/git_deploy_key') if key.nil?
|
32
|
+
key
|
33
|
+
end
|
26
34
|
Pathname.new('/home/shipitron/.ssh/id_rsa').open('w') do |file|
|
27
35
|
file.puts(deploy_key.to_s)
|
28
36
|
file.chmod(0600)
|
@@ -25,7 +25,7 @@ module Shipitron
|
|
25
25
|
else
|
26
26
|
Logger.info 'Fetching new git commits'
|
27
27
|
FileUtils.cd('/home/shipitron/git-cache') do
|
28
|
-
`git fetch #{Shellwords.escape repository_url} #{Shellwords.escape repository_branch}:#{Shellwords.escape repository_branch}`
|
28
|
+
`git fetch -f #{Shellwords.escape repository_url} #{Shellwords.escape repository_branch}:#{Shellwords.escape repository_branch}`
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -8,7 +8,7 @@ module Shipitron
|
|
8
8
|
include EcsClient
|
9
9
|
|
10
10
|
required :region
|
11
|
-
required :
|
11
|
+
required :clusters
|
12
12
|
optional :post_builds
|
13
13
|
|
14
14
|
def call
|
@@ -20,7 +20,7 @@ module Shipitron
|
|
20
20
|
post_builds.each do |post_build|
|
21
21
|
Logger.info "Running #{post_build.command}"
|
22
22
|
response = ecs_client(region: region).run_task(
|
23
|
-
cluster:
|
23
|
+
cluster: clusters.first,
|
24
24
|
task_definition: post_build.ecs_task,
|
25
25
|
overrides: {
|
26
26
|
container_overrides: [
|
@@ -45,7 +45,7 @@ module Shipitron
|
|
45
45
|
Logger.info 'Waiting for task to finish'
|
46
46
|
loop do
|
47
47
|
response = ecs_client(region: region).describe_tasks(
|
48
|
-
cluster:
|
48
|
+
cluster: clusters.first,
|
49
49
|
tasks: [task_arn]
|
50
50
|
)
|
51
51
|
next if response.tasks.empty?
|
@@ -72,8 +72,8 @@ module Shipitron
|
|
72
72
|
context.region
|
73
73
|
end
|
74
74
|
|
75
|
-
def
|
76
|
-
context.
|
75
|
+
def clusters
|
76
|
+
context.clusters
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
@@ -14,8 +14,9 @@ module Shipitron
|
|
14
14
|
optional :repository_branch
|
15
15
|
required :s3_cache_bucket
|
16
16
|
required :image_name
|
17
|
+
required :named_tag
|
17
18
|
required :region
|
18
|
-
required :
|
19
|
+
required :clusters
|
19
20
|
required :ecs_task_defs
|
20
21
|
optional :ecs_task_def_templates
|
21
22
|
optional :ecs_services
|
@@ -36,8 +37,9 @@ module Shipitron
|
|
36
37
|
repository_url
|
37
38
|
repository_branch
|
38
39
|
s3_cache_bucket
|
40
|
+
named_tag
|
39
41
|
region
|
40
|
-
|
42
|
+
clusters
|
41
43
|
ecs_services
|
42
44
|
build_script
|
43
45
|
].each_with_object(cli_args) { |k, args| args[k] = context[k] }
|
@@ -29,7 +29,12 @@ module Shipitron
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def deploy_ref_key
|
32
|
-
fetch_key
|
32
|
+
key = fetch_key(key: "shipitron/#{application}/deploy_ref_key")
|
33
|
+
if key.nil?
|
34
|
+
key = "shipitron/#{application}/deploy_ref"
|
35
|
+
Logger.info "Defaulting deploy_ref_key to #{key}"
|
36
|
+
end
|
37
|
+
key
|
33
38
|
end
|
34
39
|
end
|
35
40
|
end
|
@@ -9,7 +9,7 @@ module Shipitron
|
|
9
9
|
include EcsClient
|
10
10
|
|
11
11
|
required :region
|
12
|
-
required :
|
12
|
+
required :clusters
|
13
13
|
optional :ecs_services
|
14
14
|
required :ecs_task_defs
|
15
15
|
optional :ecs_service_templates
|
@@ -28,56 +28,57 @@ module Shipitron
|
|
28
28
|
Logger.info "Updating ECS services [#{ecs_services.join(', ')}] with task definitions [#{ecs_task_defs.map(&:to_s).join(', ')}]"
|
29
29
|
|
30
30
|
begin
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
clusters.each do |cluster_name|
|
32
|
+
service_templates = ParseTemplates.call!(
|
33
|
+
templates: ecs_service_templates,
|
34
|
+
template_context: {
|
35
|
+
cluster: cluster_name,
|
36
|
+
revision: nil,
|
37
|
+
count: nil
|
38
|
+
}
|
39
|
+
).parsed_templates
|
40
|
+
|
41
|
+
service_task_defs = {}
|
42
|
+
|
43
|
+
# Find all requested services
|
44
|
+
services_response = ecs_client(region: region).describe_services(
|
34
45
|
cluster: cluster_name,
|
35
|
-
|
36
|
-
count: nil
|
37
|
-
}
|
38
|
-
).parsed_templates
|
39
|
-
|
40
|
-
service_task_defs = {}
|
41
|
-
|
42
|
-
# Find all requested services
|
43
|
-
services_response = ecs_client(region: region).describe_services(
|
44
|
-
cluster: cluster_name,
|
45
|
-
services: ecs_services
|
46
|
-
)
|
47
|
-
|
48
|
-
# For each service, find the task definition it references
|
49
|
-
services_response.services.each do |service|
|
50
|
-
response = ecs_client(region: region).describe_task_definition(
|
51
|
-
task_definition: service.task_definition
|
46
|
+
services: ecs_services
|
52
47
|
)
|
53
48
|
|
54
|
-
# For
|
55
|
-
|
56
|
-
|
57
|
-
|
49
|
+
# For each service, find the task definition it references
|
50
|
+
services_response.services.each do |service|
|
51
|
+
response = ecs_client(region: region).describe_task_definition(
|
52
|
+
task_definition: service.task_definition
|
53
|
+
)
|
58
54
|
|
59
|
-
|
60
|
-
|
55
|
+
# For the task definition, find the locally updated version in ecs_task_defs
|
56
|
+
ecs_task_def = ecs_task_defs.find {|task| task.name == response.task_definition.family }
|
57
|
+
service_task_defs[service.service_name] = ecs_task_def
|
58
|
+
end
|
61
59
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
60
|
+
service_task_defs.each do |ecs_service, ecs_task_def|
|
61
|
+
Logger.info "#{cluster_name}: Updating #{ecs_service} with #{ecs_task_def}"
|
62
|
+
|
63
|
+
service_params = {
|
64
|
+
cluster: cluster_name,
|
65
|
+
service: ecs_service,
|
66
|
+
task_definition: ecs_task_def.name_with_revision
|
67
|
+
}
|
68
|
+
|
69
|
+
template = service_templates.find {|t| t.service_name == ecs_service }
|
70
|
+
if template != nil
|
71
|
+
if template.deployment_configuration != nil
|
72
|
+
Logger.debug "Merging deployment config: #{template.deployment_configuration}"
|
73
|
+
service_params.merge(
|
74
|
+
deployment_configuration: template.deployment_configuration
|
75
|
+
)
|
76
|
+
end
|
75
77
|
end
|
76
|
-
end
|
77
78
|
|
78
|
-
|
79
|
+
ecs_client(region: region).update_service(service_params)
|
80
|
+
end
|
79
81
|
end
|
80
|
-
|
81
82
|
rescue Aws::ECS::Errors::ServiceError => e
|
82
83
|
fail_with_errors!(messages: [
|
83
84
|
"Error: #{e.message}",
|
@@ -91,8 +92,8 @@ module Shipitron
|
|
91
92
|
context.region
|
92
93
|
end
|
93
94
|
|
94
|
-
def
|
95
|
-
context.
|
95
|
+
def clusters
|
96
|
+
context.clusters
|
96
97
|
end
|
97
98
|
|
98
99
|
def ecs_services
|
data/lib/shipitron/version.rb
CHANGED
data/shipitron.gemspec
CHANGED
@@ -17,21 +17,23 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_runtime_dependency 'thor', '~> 0.
|
21
|
-
spec.add_runtime_dependency 'aws-sdk', '~>
|
22
|
-
spec.add_runtime_dependency 'hashie', '~> 3.
|
20
|
+
spec.add_runtime_dependency 'thor', '~> 0.20'
|
21
|
+
spec.add_runtime_dependency 'aws-sdk-ecs', '~> 1.8'
|
22
|
+
spec.add_runtime_dependency 'hashie', '~> 3.5'
|
23
23
|
spec.add_runtime_dependency 'metaractor', '~> 0.5'
|
24
|
-
spec.add_runtime_dependency 'diplomat', '~> 0
|
25
|
-
spec.add_runtime_dependency 'fog-aws', '~> 0
|
26
|
-
spec.add_runtime_dependency 'mime-types', '~> 3.
|
27
|
-
spec.add_runtime_dependency 'minitar', '~> 0.
|
24
|
+
spec.add_runtime_dependency 'diplomat', '~> 2.0'
|
25
|
+
spec.add_runtime_dependency 'fog-aws', '~> 2.0'
|
26
|
+
spec.add_runtime_dependency 'mime-types', '~> 3.1'
|
27
|
+
spec.add_runtime_dependency 'minitar', '~> 0.6'
|
28
28
|
spec.add_runtime_dependency 'mustache', '~> 1.0'
|
29
|
-
spec.add_runtime_dependency 'tty-command', '~> 0.
|
29
|
+
spec.add_runtime_dependency 'tty-command', '~> 0.7'
|
30
|
+
spec.add_runtime_dependency 'tty-table', '~> 0.9'
|
31
|
+
spec.add_runtime_dependency 'pastel', '~> 0.7'
|
30
32
|
|
31
|
-
spec.add_development_dependency "bundler", "~> 1.
|
32
|
-
spec.add_development_dependency "rake", "~>
|
33
|
-
spec.add_development_dependency "pry-byebug", "~> 3.
|
34
|
-
spec.add_development_dependency "rspec", "~> 3.
|
33
|
+
spec.add_development_dependency "bundler", "~> 1.16"
|
34
|
+
spec.add_development_dependency "rake", "~> 12.3"
|
35
|
+
spec.add_development_dependency "pry-byebug", "~> 3.5"
|
36
|
+
spec.add_development_dependency "rspec", "~> 3.7"
|
35
37
|
spec.add_development_dependency "fivemat", "~> 1.3"
|
36
|
-
spec.add_development_dependency "fog-local", "~> 0.
|
38
|
+
spec.add_development_dependency "fog-local", "~> 0.4"
|
37
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shipitron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Schlesinger
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -16,42 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.20'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
26
|
+
version: '0.20'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: aws-sdk
|
28
|
+
name: aws-sdk-ecs
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '1.8'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '1.8'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: hashie
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3.
|
47
|
+
version: '3.5'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '3.
|
54
|
+
version: '3.5'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: metaractor
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,56 +72,56 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0
|
75
|
+
version: '2.0'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0
|
82
|
+
version: '2.0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: fog-aws
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0
|
89
|
+
version: '2.0'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0
|
96
|
+
version: '2.0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: mime-types
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '3.
|
103
|
+
version: '3.1'
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '3.
|
110
|
+
version: '3.1'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: minitar
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '0.
|
117
|
+
version: '0.6'
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0.
|
124
|
+
version: '0.6'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: mustache
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,70 +142,98 @@ dependencies:
|
|
142
142
|
requirements:
|
143
143
|
- - "~>"
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: '0.
|
145
|
+
version: '0.7'
|
146
146
|
type: :runtime
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: '0.
|
152
|
+
version: '0.7'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: tty-table
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0.9'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.9'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: pastel
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0.7'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0.7'
|
153
181
|
- !ruby/object:Gem::Dependency
|
154
182
|
name: bundler
|
155
183
|
requirement: !ruby/object:Gem::Requirement
|
156
184
|
requirements:
|
157
185
|
- - "~>"
|
158
186
|
- !ruby/object:Gem::Version
|
159
|
-
version: '1.
|
187
|
+
version: '1.16'
|
160
188
|
type: :development
|
161
189
|
prerelease: false
|
162
190
|
version_requirements: !ruby/object:Gem::Requirement
|
163
191
|
requirements:
|
164
192
|
- - "~>"
|
165
193
|
- !ruby/object:Gem::Version
|
166
|
-
version: '1.
|
194
|
+
version: '1.16'
|
167
195
|
- !ruby/object:Gem::Dependency
|
168
196
|
name: rake
|
169
197
|
requirement: !ruby/object:Gem::Requirement
|
170
198
|
requirements:
|
171
199
|
- - "~>"
|
172
200
|
- !ruby/object:Gem::Version
|
173
|
-
version: '
|
201
|
+
version: '12.3'
|
174
202
|
type: :development
|
175
203
|
prerelease: false
|
176
204
|
version_requirements: !ruby/object:Gem::Requirement
|
177
205
|
requirements:
|
178
206
|
- - "~>"
|
179
207
|
- !ruby/object:Gem::Version
|
180
|
-
version: '
|
208
|
+
version: '12.3'
|
181
209
|
- !ruby/object:Gem::Dependency
|
182
210
|
name: pry-byebug
|
183
211
|
requirement: !ruby/object:Gem::Requirement
|
184
212
|
requirements:
|
185
213
|
- - "~>"
|
186
214
|
- !ruby/object:Gem::Version
|
187
|
-
version: '3.
|
215
|
+
version: '3.5'
|
188
216
|
type: :development
|
189
217
|
prerelease: false
|
190
218
|
version_requirements: !ruby/object:Gem::Requirement
|
191
219
|
requirements:
|
192
220
|
- - "~>"
|
193
221
|
- !ruby/object:Gem::Version
|
194
|
-
version: '3.
|
222
|
+
version: '3.5'
|
195
223
|
- !ruby/object:Gem::Dependency
|
196
224
|
name: rspec
|
197
225
|
requirement: !ruby/object:Gem::Requirement
|
198
226
|
requirements:
|
199
227
|
- - "~>"
|
200
228
|
- !ruby/object:Gem::Version
|
201
|
-
version: '3.
|
229
|
+
version: '3.7'
|
202
230
|
type: :development
|
203
231
|
prerelease: false
|
204
232
|
version_requirements: !ruby/object:Gem::Requirement
|
205
233
|
requirements:
|
206
234
|
- - "~>"
|
207
235
|
- !ruby/object:Gem::Version
|
208
|
-
version: '3.
|
236
|
+
version: '3.7'
|
209
237
|
- !ruby/object:Gem::Dependency
|
210
238
|
name: fivemat
|
211
239
|
requirement: !ruby/object:Gem::Requirement
|
@@ -226,14 +254,14 @@ dependencies:
|
|
226
254
|
requirements:
|
227
255
|
- - "~>"
|
228
256
|
- !ruby/object:Gem::Version
|
229
|
-
version: '0.
|
257
|
+
version: '0.4'
|
230
258
|
type: :development
|
231
259
|
prerelease: false
|
232
260
|
version_requirements: !ruby/object:Gem::Requirement
|
233
261
|
requirements:
|
234
262
|
- - "~>"
|
235
263
|
- !ruby/object:Gem::Version
|
236
|
-
version: '0.
|
264
|
+
version: '0.4'
|
237
265
|
description:
|
238
266
|
email:
|
239
267
|
- ryan@outstand.com
|
@@ -259,6 +287,7 @@ files:
|
|
259
287
|
- lib/shipitron/client/create_ecs_services.rb
|
260
288
|
- lib/shipitron/client/deploy_application.rb
|
261
289
|
- lib/shipitron/client/ensure_deploy_not_running.rb
|
290
|
+
- lib/shipitron/client/fetch_clusters.rb
|
262
291
|
- lib/shipitron/client/load_application_config.rb
|
263
292
|
- lib/shipitron/client/load_templates.rb
|
264
293
|
- lib/shipitron/client/register_ecs_task_definitions.rb
|
@@ -317,7 +346,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
317
346
|
version: '0'
|
318
347
|
requirements: []
|
319
348
|
rubyforge_project:
|
320
|
-
rubygems_version: 2.
|
349
|
+
rubygems_version: 2.7.4
|
321
350
|
signing_key:
|
322
351
|
specification_version: 4
|
323
352
|
summary: A deployment tool for use with Docker and ECS.
|