Skip to content

Commit 5eb1de9

Browse files
authored
Capistrano: add task deploy:preinstall to preinstall ruby and bundled gems (#144)
Capistrano: cap deploy:setup should be safe on existing deployments Drop support for Rails 6.1 Fix rubocop plugin warning
1 parent 6863682 commit 5eb1de9

File tree

7 files changed

+67
-18
lines changed

7 files changed

+67
-18
lines changed

.github/workflows/test.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ jobs:
1212
- '3.2'
1313
- '3.3'
1414
gemfile:
15-
- gemfiles/Gemfile.rails61
1615
- gemfiles/Gemfile.rails70
1716
- gemfiles/Gemfile.rails71
1817
- gemfiles/Gemfile.rails72

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
## [Unreleased]
22
### Fixed
33
* Capistrano: Add missing `tmpdir` requirement to deploy application secrets
4+
* Capistrano: cap deploy:setup should be safe on existing deployments
5+
6+
### Added
7+
* Capistrano: add task deploy:preinstall to preinstall ruby and bundled gems
8+
9+
## Changed
10+
* Drop support for Rails 6.1
411

512
## 7.3.1 / 2025-01-02
613
### Added

config/rubocop/ndr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#
55
# See the README for instructions on using in a project.
66

7-
require:
7+
plugins:
88
- rubocop-rails
99
- rubocop-rake
1010

gemfiles/Gemfile.rails61

Lines changed: 0 additions & 7 deletions
This file was deleted.

lib/ndr_dev_support/capistrano/ndr_model.rb

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
require_relative 'assets'
55
require_relative 'deploy_secrets'
66
require_relative 'install_ruby'
7+
require_relative 'preinstall'
78
require_relative 'restart'
89
require_relative 'revision_logger'
910
require_relative 'ruby_version'
@@ -53,11 +54,15 @@
5354
# sticky; all deployments made within it should be owned by the deployer group too. This
5455
# means that e.g. a deployment by "bob.smith" can then be rolled back by "tom.jones".
5556
run "mkdir -p #{deploy_to}"
56-
run "chgrp -R deployer #{deploy_to}"
57+
# Set deployer group for everything created by this user
58+
# run "chgrp -R deployer #{deploy_to}"
59+
run "find #{deploy_to} -group #{fetch(:user)} -print0 |xargs -r0 chgrp -h deployer"
5760

5861
# The sticky group will apply automatically to new subdirectories, but
5962
# any existing subdirectories will need it manually applying via `-R`.
60-
run "chmod -R g+s #{deploy_to}"
63+
# run "chmod -R g+s #{deploy_to}"
64+
run "find #{deploy_to} -user #{fetch(:user)} -type d " \
65+
'-not -perm -2000 -print0 |xargs -r0 chmod g+s'
6166
end
6267

6368
desc 'Custom tasks to be run once, after the initial `cap setup`'
@@ -67,8 +72,12 @@
6772
run "mkdir -p #{full_path}"
6873

6974
# Allow the application to write into here:
70-
run "chgrp -R #{application_group} #{full_path}"
71-
run "chmod -R g+s #{full_path}"
75+
# run "chgrp -R #{application_group} #{full_path}"
76+
# run "chmod -R g+s #{full_path}"
77+
run "find #{full_path} -user #{fetch(:user)} -not -group #{application_group} " \
78+
"-print0 |xargs -r0 chgrp -h #{application_group}"
79+
run "find #{full_path} -user #{fetch(:user)} -type d " \
80+
'-not -perm -2000 -print0 |xargs -r0 chmod g+s'
7281
end
7382

7483
fetch(:shared_paths, []).each do |path|
@@ -185,6 +194,14 @@ def target_ruby_version_for(env)
185194
match ? match[:version] : raise('Unrecognized Ruby version!')
186195
end
187196

197+
def log_deployment_message(msg)
198+
name = fetch(:deployer_name, capture('id -un').chomp)
199+
log = File.join(shared_path, 'revisions.log')
200+
msg = "[#{Time.now}] #{name} #{msg}" # rubocop:disable Rails/TimeZone
201+
202+
run "(test -e #{log} || (touch #{log} && chmod 664 #{log})) && echo #{Shellwords.escape(msg)} >> #{log};"
203+
end
204+
188205
def add_target(env, name, app, port, app_user, is_web_server)
189206
desc "Deploy to #{env} service #{app_user || 'you'}@#{app}:#{port}"
190207
task(name) do
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
Capistrano::Configuration.instance(:must_exist).load do
2+
namespace :deploy do
3+
desc <<~DESC
4+
Preinstall ruby and gems, then abort and rollback cleanly, leaving the
5+
current installation unchanged.
6+
7+
This is particularly useful for ruby version bumps: installing the new
8+
ruby version and all the bundled gems can take a long time.
9+
10+
This aborts before updating out-of-bundle gems, in case that causes
11+
issues when restarting the currently installed version.
12+
13+
Usage:
14+
cap target deploy:preinstall
15+
DESC
16+
task :preinstall do
17+
# Running this task sets a flag, to make ndr_dev_support:check_preinstall abort.
18+
# We do this in a roundabout way on Capistrano 2, because deploy:update_code
19+
# explicitly runs deploy:finalize_update, instead of using task dependencies.
20+
set :preinstall, true
21+
end
22+
end
23+
24+
namespace :ndr_dev_support do
25+
desc 'Hook to abort capistrano installation early after preinstalling ruby and in-bundle gems'
26+
task :check_preinstall do
27+
next unless fetch(:preinstall, false)
28+
29+
log_deployment_message("preinstalled #{real_revision}")
30+
warn Rainbow("Successful preinstall for target: #{fetch(:name)}")
31+
abort 'Aborting after successful preinstall'
32+
end
33+
end
34+
35+
after 'deploy:preinstall', 'deploy:update'
36+
before 'ndr_dev_support:update_out_of_bundle_gems', 'ndr_dev_support:check_preinstall'
37+
end

lib/ndr_dev_support/capistrano/revision_logger.rb

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22
namespace :ndr_dev_support do
33
desc 'Append to the log of deployments the user and revision.'
44
task :log_deployment, except: { no_release: true } do
5-
name = fetch(:deployer_name, capture('id -un'))
6-
log = File.join(shared_path, 'revisions.log')
7-
msg = "[#{Time.now}] #{name} deployed #{latest_revision}"
8-
9-
run "(test -e #{log} || (touch #{log} && chmod 664 #{log})) && echo #{msg} >> #{log};"
5+
log_deployment_message("deployed #{latest_revision}")
106
end
117
end
128

0 commit comments

Comments
 (0)