capistrano_dockerbuild 1.0.0 → 1.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4d0d051fdc506aceb1bbc232079f1f04fb2e0b9f
4
- data.tar.gz: c0182416f4b9c3fc338fc63d6f89c8d933fe6847
3
+ metadata.gz: 4ce4c53bd25ff86f3b5e2237b0605b9253b3627a
4
+ data.tar.gz: 8c139b49008bdc0716fee7999e0d63b36e229234
5
5
  SHA512:
6
- metadata.gz: b94b0a4e491a17c8a1c32fc2f3898031296438dd3603c40b21606871f6d607acf031a70f49b3e37e1b37fb6988c58ce4d5bed9007755f42cc6cd9239e07092d1
7
- data.tar.gz: e483d3ff6866501200b070b7910d218cc73cc1fbeff7ca8cc77f85b9d80f5ee8f187c4f92c1c5b579773beba045c9fa96d8e333387a157d69790dfd89710eb16
6
+ metadata.gz: d7f6fa7928ff96fb9571bba1c0edcfda610e94bb0cd6e7d3a12473ee4a577d40385dc0b785be2bbf1c751026160264a5ac93b5bef065f57530522887f6e0ec6f
7
+ data.tar.gz: 57a5f9acf9bef342fc51be5b8796abc74742643921f0eaa62cc11c0012aa79130c634d024469f992e1a60e17ebda3a56cf4def2ae69e487f13a10b4b50103c85
data/.rubocop.yml CHANGED
@@ -44,6 +44,10 @@ Layout/EmptyLinesAroundClassBody:
44
44
  Layout/EmptyLines:
45
45
  Enabled: false
46
46
 
47
+ Metrics/PerceivedComplexity:
48
+ Enabled: false
49
+ Metrics/CyclomaticComplexity:
50
+ Enabled: false
47
51
  Metrics/BlockLength:
48
52
  Enabled: false
49
53
  Metrics/AbcSize:
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ source 'https://rubygems.org'
5
5
  # Specify your gem's dependencies in capistrano-docker-build.gemspec
6
6
  gemspec
7
7
 
8
- gem 'byebug'
8
+ # gem 'byebug'
9
9
  gem 'rspec'
10
10
  gem 'rspec-core'
11
11
  gem 'pry'
@@ -1,4 +1,4 @@
1
- This content is specific to deployments using docker-compose; if you haven't yet reviewed README.md, you should probably start there.
1
+ _This content is specific to deployments using docker-compose; if you haven't yet reviewed README.md, you should probably start there._
2
2
 
3
3
  # docker:compose
4
4
 
@@ -11,16 +11,16 @@ There is no blue/green, rolling update, auto rollback on failure, or anything ev
11
11
 
12
12
  ### Roles:
13
13
 
14
- This gem adds the `docker_compose` role, identifying hosts where the docker_compose_file should be copied and ran.
14
+ This plugin adds the `docker_compose` role, identifying hosts where the docker_compose_file should be copied and ran.
15
15
 
16
- If the `docker_build` role is defined, it will identify the source of the docker_compose_file
16
+ If the `docker_build` role is defined, it will identify the source of the docker_compose_file, otherwise the current project directory is the source.
17
17
 
18
18
  ```ruby
19
- # using the `server` command
19
+ # using server syntax
20
20
  server 'my.remote.server', roles: %w{docker_compose}
21
21
  server 'my_other.remote.server', roles: %w{docker_compose}
22
22
 
23
- # or using the `role` command
23
+ # or using role syntax
24
24
  role :docker_compose, %w{localhost} # places localhost within the docker_compose role
25
25
 
26
26
  # The docker_build role is used to identify the source of the docker_compose_file
@@ -1,7 +1,24 @@
1
- This content is specific to deployments using Docker Swarm; if you haven't yet reviewed README.md, you should probably start there.
1
+ _This content is specific to deployments using Docker Swarm; if you haven't yet reviewed README.md, you should probably start there._
2
2
 
3
3
  # docker:swarm
4
4
 
5
+ This deploy strategy copies a docker-compose.yml file to the docker swarms you specify, and then runs `docker stack up` across the whole lot.
6
+
7
+ Deploying to a single swarm member should be enough to deploy across the entire swarm, so choosing one deploy host per swarm is probably the best course of action.
8
+
9
+ ### Roles:
10
+
11
+ This plugin adds the `docker_swarm` role, identifying hosts where the `docker_compose_file` should be copied and ran.
12
+
13
+ If the `docker_build` role is defined, it will identify the source of the `docker_compose_file`, otherwise the current project directory is the source.
14
+
15
+ ```ruby
16
+ # using server syntax
17
+ server 'my.swarm.host', roles: %w{docker_swarm}
18
+
19
+ # or using role syntax
20
+ role :docker_swarm, %w{my.swarm.host}
21
+ ```
5
22
 
6
23
 
7
24
 
@@ -16,15 +33,3 @@ set :docker_compose_path -> { deploy_path } # path on remot
16
33
 
17
34
  set :dockerswarm_deployhook, true # set false to skip default deploy hook; default is true
18
35
  ```
19
-
20
- ----
21
-
22
- ```ruby
23
- set :docker_compose_project -> { fetch(:application) } # (required) name of the docker-compose project
24
- set :docker_compose_file, 'docker-compose.yml' # name of compose file to use for deploy
25
- set :docker_compose_cmd, 'docker-compose' # name/path to `docker-compose` command on host
26
- set :docker_compose_opts, nil # general args for `docker-compose`; default is none; (ex: '--project-name myproject --tls')
27
- set :docker_compose_up_opts, '-d --no-build --remove-orphans' # args for `docker-compose up` command; these are the defaults
28
- set :docker_compose_stop_opts, nil # args for `docker-compose stop` command; default is none; (ex: '--timeout 20')
29
- set :dockercompose_deployhook, true # set false to skip default deploy hook; default is true
30
- ```
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # capistrano_dockerbuild
2
2
 
3
- Docker image creation, tagging, and repository tasks (and a few optional deployment schemes) for Capistrano v3
3
+ Docker image creation, tagging, and repository tasks for Capistrano v3
4
4
 
5
5
  ```sh
6
- cap production docker:build_push # build image and then push to repository
6
+ cap production docker:deploy # build or promote image and push to repository
7
7
  ```
8
8
 
9
9
  This plugin also hooks into the default `cap <environment> deploy` flow as a build action. See [Usage](#usage) for more details.
@@ -47,7 +47,7 @@ role :docker_build, %w{localhost} # role syntax, making localhost the build age
47
47
  server 'my.build.server', roles: %w{docker_build} # server syntax, declaring a remote server
48
48
  ```
49
49
 
50
- If no `:docker_build` host is defined, the docker image will be built directly from the current working project directory. A maximum of one `:docker_build` host can be defined; any additional should raise an error.
50
+ If no `:docker_build` host is defined, the docker image will be built directly from the current working project directory. A maximum of one `:docker_build` host can be defined.
51
51
 
52
52
  #### Run a deploy:
53
53
 
@@ -74,27 +74,37 @@ Run `cap -T docker:` for details
74
74
  ```ruby
75
75
  set :docker_build_image -> { fetch(:application) } # (required) name of the image
76
76
  set :docker_build_opts, nil # additional `docker build` args; default is none; (ex: '--pull --no-cache --force-rm')
77
- set :docker_build_tag, 'latest' # specific tag name for this build; you can change this and 'latest' tag will still be applied
77
+ set :docker_build_custom_tag, nil # custom tag name for this build, if any
78
+ set :docker_build_image_latest_tag?, true # generates a 'latest' tag when true
79
+ set :docker_build_image_release_tag?, true # generates a release tag when true
80
+ set :docker_build_image_revision_tag?, true # generates a scm revision tag when true
81
+ set :docker_build_image_shortrev_tag?, true # generates a short-form scm revision tag when true
78
82
  set :docker_repo_url, nil # name/url of remote docker image repository for push
79
- set :docker_build_context, '.' # context passed to `docker build` (within :build_from)
83
+ set :docker_build_context, '.' # context passed to `docker build` (from :build_dir)
80
84
  set :dockerfile, 'Dockerfile' # name of Dockerfile to use for build
81
85
  set :docker_cmd, 'docker' # name/path to `docker` command on build host
82
- set :build_from, '.' # directory within source repo to run build from
86
+ set :build_dir, '.' # directory within source repository to run builds from on remote build hosts
87
+ set :docker_build_promote_image, nil # repository/image:tag to promote instead of building a new image
83
88
  set :dockerbuild_deployhook, true # set false to skip default deploy hook; default is true
84
89
  set :dockerbuild_trim_release_roles, true # set false to prevent no_release from being auto-added to all non docker_build servers
85
90
  ```
86
91
 
87
- ### Created Docker image tags
88
- Under most use cases the `docker:build` task creates several image tags on the build host upon completion, all pointing to the same image SHA. By default, all of these tags are also pushed up to the docker image repository during the `docker:push` task. You may not want your repository (or build host) filled with a ton of tags, so this gem offers a few ways to control that sprawl.
92
+ ### Created docker image tags
93
+
94
+ By default the `docker:build` task creates several image tags on the build host upon completion, all pointing to the same final image. Unless otherwise altered, all created tags are also pushed up to the docker image repository during the `docker:push` task. You may not want your repository (or build host) filled with a ton of tags, so this gem offers a few ways to control that sprawl.
95
+
96
+ You can selectively turn off remotely pushed tags by setting these to `false`, as desired:
97
+
98
+ - `:docker_build_image_latest_tag?`
99
+ - `:docker_build_image_release_tag?`
100
+ - `:docker_build_image_revision_tag?`
101
+ - `:docker_build_image_shortrev_tag?`
102
+
103
+ `:docker_build_custom_tag` is optional; if you don't want a custom tag created, don't set one.
89
104
 
90
- docker_build_image_latest_tag,
91
- docker_build_image_revision_tag,
92
- docker_build_image_shortrev_tag,
93
- docker_build_image_release_tag,
94
- docker_build_image_tag,
95
105
 
96
106
  ### Deployment to docker-compose, Docker Swarm, Kubernetes, Marathon, etc
97
- The primary purpose of this gem is currently to provide tasks for Docker image creation and repository push/transfer. However, some basic deployment tasks are included as optionals, should you decide to use them. Each deploy strategy needs to be specifically enabled by a separate `requires` statement within your Capfile.
107
+ The primary goal of this gem is currently to provide tasks for Docker image creation and repository push/transfer. However, some deployment tasks are also included, should you decide to use them. Each deploy strategy needs to be specifically enabled by a separate `requires` statement within your Capfile.
98
108
 
99
109
  Refer to the specific deployment documentation for details:
100
110
 
@@ -105,9 +115,11 @@ Refer to the specific deployment documentation for details:
105
115
 
106
116
  Because.
107
117
 
118
+ There are at least a dozen other Capistrano + Docker gems out there, but none seemed to match my preferred docker philosophy: Docker images should be built once and then promoted up to higher environments as they pass acceptance tests. This gem aims to provide that type of workflow.
119
+
108
120
  ## Development
109
121
 
110
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
122
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
111
123
 
112
124
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
113
125
 
@@ -6,12 +6,14 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
6
 
7
7
  Gem::Specification.new do |spec|
8
8
  spec.name = 'capistrano_dockerbuild'
9
- spec.version = '1.0.0'
9
+ spec.version = '1.1.1'
10
10
  spec.authors = ['Eric Shorkey']
11
11
  spec.email = ['eric.shorkey@gmail.com']
12
12
 
13
13
  spec.summary = 'docker build/push plugin for Capistrano'
14
- spec.description = 'Build, push and deploy your Docker container images as part of your Capistrano workflow. Pretty simple.'
14
+ spec.description = 'Build, push, promote, and deploy Docker container images with Capistrano.' \
15
+ ' Build images locally or from a build server, rebuild or promote images across deployment environments.' \
16
+ ' Deployments for docker-compose and docker swarm.'
15
17
  spec.homepage = 'https://github.com/eshork/capistrano_dockerbuild'
16
18
  spec.license = 'MIT'
17
19
 
@@ -4,16 +4,16 @@ module Capistrano
4
4
  module DSL
5
5
  module Paths
6
6
 
7
- def build_from
8
- fetch(:build_from)
7
+ def build_dir
8
+ fetch(:build_dir)
9
9
  end
10
10
 
11
11
  # directory within which the build is to be executed
12
12
  # respects relative paths (not starting with /)
13
13
  def build_path
14
- return deploy_path.join(fetch(:current_directory, 'current')) if build_from.nil?
15
- return Pathname.new(build_from.strip) if build_from.strip[0] == '/'
16
- return deploy_path.join(fetch(:current_directory, 'current'), build_from)
14
+ return deploy_path.join(fetch(:current_directory, 'current')) if build_dir.nil?
15
+ return Pathname.new(build_dir.strip) if build_dir.strip[0] == '/'
16
+ return deploy_path.join(fetch(:current_directory, 'current'), build_dir)
17
17
  end
18
18
 
19
19
  end
@@ -2,6 +2,74 @@
2
2
 
3
3
  namespace :docker do
4
4
 
5
+ class DockerImage
6
+ def initialize(repo = nil, name = nil, tag = nil)
7
+ @repository = repo.nil? || repo.empty? ? nil : repo
8
+ @name = name.nil? || name.empty? ? nil : name
9
+ @tag = tag.nil? || tag.empty? ? nil : tag
10
+ end
11
+
12
+ def to_s
13
+ return nil unless @name
14
+ "#{@repository ? "#{@repository}/" : nil}#{@name}#{@tag ? ":#{@tag}" : nil}"
15
+ end
16
+
17
+ def repo
18
+ return @repository
19
+ end
20
+
21
+ def name
22
+ return @name
23
+ end
24
+
25
+ def tag
26
+ return @tag
27
+ end
28
+
29
+ def valid?
30
+ return false if @repository.nil? && @name.nil? && @tag.nil?
31
+ unless @repository.nil?
32
+ return false if (@repository =~ /^([\d\w])*(:)?\d*$/).nil?
33
+ end
34
+ return false if (@name =~ /^([\d\w])*$/).nil?
35
+ unless @tag.nil?
36
+ return false if (@tag =~ /^([\d\w-])*$/).nil?
37
+ end
38
+ return true
39
+ end
40
+
41
+ def self.from_str(str)
42
+ return new unless str
43
+ repo_str = repo_from_str(str)
44
+ name_str = name_from_str(str)
45
+ tag_str = tag_from_str(str)
46
+ return new repo_str, name_str, tag_str
47
+ end
48
+
49
+ def self.repo_from_str(str)
50
+ last_slash = str.rindex('/')
51
+ return nil unless last_slash
52
+ return str[0...last_slash]
53
+ end
54
+
55
+ def self.name_from_str(str)
56
+ # remove any repo bits
57
+ repo_str = repo_from_str(str)
58
+ str = str.sub("#{repo_str}/", '') if repo_str
59
+ # remove any tag bits
60
+ str.split(':')[0]
61
+ end
62
+
63
+ def self.tag_from_str(str)
64
+ # remove any repo bits
65
+ repo_str = repo_from_str(str)
66
+ str = str.sub("#{repo_str}/", '') if repo_str
67
+ # remove any name bits
68
+ str_split = str.split(':')
69
+ return str_split.size > 1 ? str_split[1] : nil
70
+ end
71
+ end
72
+
5
73
  # Any extra command-line opts you'd like to insert into the `docker build` command
6
74
  # Normally has no preset value (fastest option), but a popular full-rebuild-every-time (thorough build) selection is '--pull --no-cache --force-rm'
7
75
  def docker_build_opts
@@ -26,13 +94,13 @@ namespace :docker do
26
94
  (fetch(:docker_build_image) { fetch(:application) }) || raise('unable to discern docker_build_image name; specify :application or :docker_build_image')
27
95
  end
28
96
 
29
- def docker_build_tag
30
- fetch(:docker_build_tag, 'latest')
97
+ def docker_build_custom_tag
98
+ return nil unless fetch(:docker_build_custom_tag, nil)
99
+ return "#{docker_build_image}:#{fetch(:docker_build_custom_tag)}"
31
100
  end
32
101
 
33
- def docker_build_image_tag
34
- return fetch(:docker_build_image_tag) ||
35
- set(:docker_build_image_tag, "#{docker_build_image}:#{docker_build_tag}")
102
+ def docker_build_image_latest_tag?
103
+ return fetch(:docker_build_image_latest_tag?, true)
36
104
  end
37
105
 
38
106
  def docker_build_image_latest_tag
@@ -40,17 +108,29 @@ namespace :docker do
40
108
  set(:docker_build_image_latest_tag, "#{docker_build_image}:latest")
41
109
  end
42
110
 
111
+ def docker_build_image_release_tag?
112
+ return fetch(:docker_build_image_release_tag?, true)
113
+ end
114
+
43
115
  def docker_build_image_release_tag
44
116
  return fetch(:docker_build_image_release_tag) ||
45
117
  set(:docker_build_image_release_tag, "#{docker_build_image}:release-#{release_timestamp}")
46
118
  end
47
119
 
120
+ def docker_build_image_revision_tag?
121
+ return fetch(:docker_build_image_revision_tag?, true)
122
+ end
123
+
48
124
  def docker_build_image_revision_tag
49
125
  return nil unless fetch(:current_revision)
50
126
  return fetch(:docker_build_image_revision_tag) ||
51
127
  set(:docker_build_image_revision_tag, "#{docker_build_image}:REVISION-#{fetch(:current_revision)}")
52
128
  end
53
129
 
130
+ def docker_build_image_shortrev_tag?
131
+ return fetch(:docker_build_image_shortrev_tag?, true)
132
+ end
133
+
54
134
  def docker_build_image_shortrev_tag
55
135
  return nil unless fetch(:current_revision)
56
136
  return fetch(:docker_build_image_shortrev_tag) ||
@@ -58,13 +138,13 @@ namespace :docker do
58
138
  end
59
139
 
60
140
  def docker_build_image_tags
61
- [
62
- docker_build_image_latest_tag,
63
- docker_build_image_revision_tag,
64
- docker_build_image_shortrev_tag,
65
- docker_build_image_release_tag,
66
- docker_build_image_tag,
67
- ].uniq.compact
141
+ tags = []
142
+ tags << docker_build_custom_tag if docker_build_custom_tag
143
+ tags << docker_build_image_release_tag if docker_build_image_release_tag?
144
+ tags << docker_build_image_revision_tag if docker_build_image_revision_tag?
145
+ tags << docker_build_image_shortrev_tag if docker_build_image_shortrev_tag?
146
+ tags << docker_build_image_latest_tag if docker_build_image_latest_tag?
147
+ return tags.uniq.compact
68
148
  end
69
149
 
70
150
  def docker_build_image_tags_opt
@@ -84,12 +164,17 @@ namespace :docker do
84
164
  docker_build_image_tags.map{|t| docker_repo_tag(t)}
85
165
  end
86
166
 
87
- # TODO: remove this!!!!!!!!
88
- task :debug do
89
- byebug # rubocop:disable Lint/Debugger
90
- puts 'pew pew!'
167
+ def docker_build_promote_image
168
+ promote_image_tag = fetch(:docker_build_promote_image, nil)
169
+ image_name = DockerImage.from_str(promote_image_tag)
170
+ image_name = DockerImage.new(image_name.repo ? image_name.repo : docker_repo_url,
171
+ image_name.name ? image_name.name : docker_build_image,
172
+ image_name.tag ? image_name.tag : docker_build_tag)
173
+ promote_tag = image_name.to_s
174
+ return promote_tag
91
175
  end
92
176
 
177
+
93
178
  task :check_docker_build_role do
94
179
  if roles(:docker_build).empty?
95
180
  run_locally do
@@ -132,7 +217,7 @@ namespace :docker do
132
217
  end
133
218
  end
134
219
 
135
- task :local_build_deps => [:local_build_warning]
220
+ task :local_build_deps => [:local_build_warning, :set_current_revision]
136
221
 
137
222
  task :build_local => :local_build_deps do
138
223
  current_build_dir = pwd
@@ -147,7 +232,7 @@ namespace :docker do
147
232
  end
148
233
  end
149
234
 
150
- task :remote_build_deps => [:check_docker_build_role, :check_docker_build_root]
235
+ task :remote_build_deps => [:check_docker_build_role, :check_docker_build_root, :set_current_revision]
151
236
 
152
237
  task :build_remote => :remote_build_deps do
153
238
  on roles(:docker_build).first do |buildremote|
@@ -164,79 +249,154 @@ namespace :docker do
164
249
  end
165
250
  end
166
251
 
167
- task :tag do
252
+
253
+ task :set_current_revision => 'deploy:set_current_revision'
254
+
255
+ task :get_docker_build_image_id => :set_current_revision do
256
+
257
+ run_locally do
258
+ docker_build_image_tags.each do |image_tag|
259
+ docker_build_image_id = capture docker_cmd, :image, :ls, '-q', image_tag
260
+ unless docker_build_image_id.empty?
261
+ set(:docker_build_image_id, docker_build_image_id)
262
+ break
263
+ end
264
+ end
265
+ unless fetch(:docker_build_image_id)
266
+ fatal 'unable to discern image id'
267
+ raise 'missing image id'
268
+ end
269
+ end
270
+ end
271
+
272
+
273
+ desc "Push the 'latest' image to the repository"
274
+ task :push do
168
275
  if roles(:docker_build).empty?
169
- invoke 'docker:tag_local'
276
+ invoke 'docker:push_local'
170
277
  else
171
- invoke 'docker:tag_remote'
278
+ invoke 'docker:push_remote'
172
279
  end
173
280
  end
174
281
 
175
- task :tag_local do
176
- if docker_build_image_release_tag
177
- run_locally do
178
- info 'Re-tagging docker images for upstream push...'
179
- docker_repo_tags.each do |repo_tag|
282
+ task :push_local => :get_docker_build_image_id do
283
+ run_locally do
284
+ unless docker_repo_url
285
+ warn ':docker_repo_url not defined! No push destination'
286
+ next
287
+ end
288
+ docker_build_image_tags.each do |local_tag|
289
+ repo_tag = docker_repo_tag(local_tag)
290
+ next unless repo_tag
291
+ run_locally do
180
292
  execute docker_cmd, :tag,
181
- docker_build_image_latest_tag,
293
+ fetch(:docker_build_image_id),
294
+ repo_tag
295
+ execute docker_cmd, :push,
182
296
  repo_tag
183
297
  end
184
298
  end
185
299
  end
186
300
  end
187
301
 
188
- task :tag_remote => :check_docker_build_role do
189
- if docker_build_image_release_tag
190
- on roles(:docker_build).first do # |buildremote|
191
- info 'Re-tagging docker images for upstream push...'
192
- docker_repo_tags.each do |repo_tag|
302
+ task :push_remote => [:check_docker_build_role, :get_docker_build_image_id] do
303
+ on roles(:docker_build).first do # |buildremote|
304
+ unless docker_repo_url
305
+ warn ':docker_repo_url not defined! No push destination'
306
+ next
307
+ end
308
+ docker_build_image_tags.each do |local_tag|
309
+ repo_tag = docker_repo_tag(local_tag)
310
+ next unless repo_tag
311
+ run_locally do
193
312
  execute docker_cmd, :tag,
194
- docker_build_image_latest_tag,
313
+ fetch(:docker_build_image_id),
314
+ repo_tag
315
+ execute docker_cmd, :push,
195
316
  repo_tag
196
317
  end
197
318
  end
198
319
  end
199
320
  end
200
321
 
201
- desc "Push the 'latest' image to the repository"
202
- task :push do
322
+ desc 'Build the docker image'
323
+ task :build do
324
+ invoke 'docker:build_decision'
325
+ end
326
+
327
+ desc 'Build and push docker image'
328
+ task :build_push do
329
+ invoke 'docker:build'
330
+ invoke 'docker:push'
331
+ end
332
+
333
+
334
+ desc 'Promote an existing docker image (pull and retag)'
335
+ task :promote do
203
336
  if roles(:docker_build).empty?
204
- invoke 'docker:push_local'
337
+ invoke 'docker:promote_local'
205
338
  else
206
- invoke 'docker:push_remote'
339
+ invoke 'docker:promote_remote'
207
340
  end
208
341
  end
209
342
 
210
- task :push_local => :tag_local do
343
+ task :check_docker_build_promote_image do
344
+ unless fetch :docker_build_promote_image
345
+ run_locally do
346
+ fatal ':docker_build_promote_image setting is required for promote task'
347
+ raise 'missing :docker_build_promote_image'
348
+ end
349
+ end
350
+ unless DockerImage.from_str(docker_build_promote_image).valid?
351
+ run_locally do
352
+ fatal ":docker_build_promote_image setting is not valid: '#{fetch(:docker_build_promote_image)}' => '#{docker_build_promote_image}'"
353
+ raise 'invalid :docker_build_promote_image'
354
+ end
355
+ end
356
+ end
357
+
358
+ task :promote_local => :check_docker_build_promote_image do
211
359
  run_locally do
212
- info 'Pushing docker images upstream...'
360
+ source_tag = docker_build_promote_image
361
+ info "Promoting image: #{source_tag}"
362
+ execute docker_cmd, :pull, source_tag
363
+
213
364
  docker_repo_tags.each do |repo_tag|
365
+ next if repo_tag == source_tag
366
+ info "Promoted to: #{repo_tag}"
367
+ execute docker_cmd, :tag,
368
+ source_tag,
369
+ repo_tag
214
370
  execute docker_cmd, :push,
215
371
  repo_tag
216
372
  end
373
+
217
374
  end
218
375
  end
219
376
 
220
- task :push_remote => [:check_docker_build_role, :tag_remote] do
377
+ task :promote_remote => :check_docker_build_promote_image do
221
378
  on roles(:docker_build).first do # |buildremote|
222
- info 'Pushing docker images upstream...'
379
+ source_tag = docker_build_promote_image
380
+ info "Promoting image: #{source_tag}"
381
+ execute docker_cmd, :pull, source_tag
382
+
223
383
  docker_repo_tags.each do |repo_tag|
384
+ next if repo_tag == source_tag
385
+ info "Promoted to: #{repo_tag}"
386
+ execute docker_cmd, :tag,
387
+ source_tag,
388
+ repo_tag
224
389
  execute docker_cmd, :push,
225
390
  repo_tag
226
391
  end
392
+
227
393
  end
228
394
  end
229
395
 
230
- desc 'Build the docker container image'
231
- task :build do
232
- invoke 'docker:build_decision'
233
- end
234
396
 
235
- desc 'Build and then push docker container image'
236
- task :build_push do
237
- invoke 'docker:build'
238
- invoke 'docker:push'
239
- end
397
+ desc '(alias for docker:build_push)'
398
+ task :deploy => :build_push
399
+
240
400
 
241
401
  # Default `cap env deploy` flow hook
242
402
  task :capdeploy_hook do
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'byebug'
4
3
  require 'tempfile'
5
4
 
6
5
  namespace :docker do
@@ -94,7 +93,6 @@ namespace :docker do
94
93
  download! docker_compose_path.join(docker_compose_file), tmp_file_path
95
94
  end
96
95
  else
97
- # byebug
98
96
  invoke 'docker:compose:local_source_warning'
99
97
  run_locally do
100
98
  warn "fetching #{docker_compose_file}"
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'byebug'
4
3
  require 'tempfile'
5
4
 
6
5
  namespace :docker do
@@ -2,12 +2,12 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
- RSpec.describe Capistrano::Docker::Build do
6
- it 'has a version number' do
7
- expect(Capistrano::Docker::Build::VERSION).not_to be nil
8
- end
5
+ # RSpec.describe Capistrano::Dockerbuild do
6
+ # it 'has a version number' do
7
+ # expect(Capistrano::Docker::Build::VERSION).not_to be nil
8
+ # end
9
9
 
10
- it 'does something useful' do
11
- expect(false).to eq(true)
12
- end
13
- end
10
+ # it 'does something useful' do
11
+ # expect(false).to eq(true)
12
+ # end
13
+ # end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/setup'
4
- require 'capistrano/docker/build'
4
+ # require 'capistrano/dockerbuild'
5
5
 
6
6
  RSpec.configure do |config|
7
7
  # Enable flags like --only-failures and --next-failure
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano_dockerbuild
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Shorkey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-11 00:00:00.000000000 Z
11
+ date: 2018-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capistrano
@@ -52,8 +52,9 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '12.0'
55
- description: Build, push and deploy your Docker container images as part of your Capistrano
56
- workflow. Pretty simple.
55
+ description: Build, push, promote, and deploy Docker container images with Capistrano.
56
+ Build images locally or from a build server, rebuild or promote images across deployment
57
+ environments. Deployments for docker-compose and docker swarm.
57
58
  email:
58
59
  - eric.shorkey@gmail.com
59
60
  executables: