1
0
Fork 0
mirror of https://github.com/capistrano/capistrano synced 2023-03-27 23:21:18 -04:00

Prevents last good release from being deleted on cleanup (#1922)

* Prevents last good release from being deleted on cleanup

Issue: 1907

If there are many failed deployments the relese folders will
still be left there and eventually if deploy:cleanup is
executed it will delete the release that is referenced by the
"current" symlink, potentially causing downtime.

That change will prevent the "current release" from ever being
removed during cleanup.

* Link PR on CHANGELOG

* Verify if current dir exists

Check if current release directory exists instead of relying on
exceptions being raised.
This commit is contained in:
David Michael Nelson 2017-10-12 16:40:57 -03:00 committed by Matt Brictson
parent 33c3943fa5
commit f79a386aad
5 changed files with 27 additions and 5 deletions

View file

@ -19,6 +19,7 @@ gem "capistrano", :github => "capistrano/capistrano"
[master]: https://github.com/capistrano/capistrano/compare/v3.9.1...HEAD
* Your contribution here!
* [#1922](https://github.com/capistrano/capistrano/pull/1922): Prevents last good release from being deleted during cleanup if there are too many subsequent failed deploys
* As of this release, version 2.x of Capistrano is officially End of Life. No further releases of 2.x series are planned, and pull requests against 2.x are no longer accepted. The maintainers encourage you to upgrade to 3.x if possible.
* [#1937](https://github.com/capistrano/capistrano/pull/1937): Clarify error message when plugin is required in the wrong config file.
* [#1930](https://github.com/capistrano/capistrano/issues/1930): Default to locking the version using the pessimistic version operator at the patch level.

View file

@ -60,6 +60,16 @@ Feature: Deploy
Then 3 valid releases are kept
And the invalid "new" release is ignored
Scenario: Cleanup after many failed releases doesn't remove last good release
Given config stage file has line "set :keep_releases, 2"
And I make 2 deployments
And an invalid release named "77777777777777"
And an invalid release named "88888888888888"
And an invalid release named "99999999999999"
When I run cap "deploy:cleanup"
Then 3 valid releases are kept
And the current directory will be a symlink to the release
Scenario: Rolling Back
Given I make 2 deployments
When I run cap "deploy:rollback"

View file

@ -66,7 +66,7 @@ Then(/^directory symlinks are created in the new release$/) do
end
Then(/^the current directory will be a symlink to the release$/) do
run_vagrant_command(test_symlink_exists(TestApp.current_path))
run_vagrant_command(exists?("e", TestApp.current_path))
end
Then(/^the deploy\.rb file is created$/) do

View file

@ -14,6 +14,8 @@ en = {
question_default: "Please enter %{key} (%{default_value}): ",
keeping_releases: "Keeping %{keep_releases} of %{releases} deployed releases on %{host}",
skip_cleanup: "Skipping cleanup of invalid releases on %{host}; unexpected foldername found (should be timestamp)",
wont_delete_current_release: "Current release was marked for being removed but it's going to be skipped on %{host}",
no_current_release: "There is no current release present on %{host}",
no_old_releases: "No old releases (keeping newest %{keep_releases}) on %{host}",
linked_file_does_not_exist: "linked file %{file} does not exist on %{host}",
cannot_rollback: "There are no older releases to rollback to",

View file

@ -155,11 +155,20 @@ namespace :deploy do
if valid.count >= fetch(:keep_releases)
info t(:keeping_releases, host: host.to_s, keep_releases: fetch(:keep_releases), releases: valid.count)
directories = (valid - valid.last(fetch(:keep_releases)))
directories = (valid - valid.last(fetch(:keep_releases))).map do |release|
releases_path.join(release).to_s
end
if test("[ -d #{current_path} ]")
current_release = capture(:readlink, current_path).to_s
if directories.include?(current_release)
warn t(:wont_delete_current_release, host: host.to_s)
directories.delete(current_release)
end
else
debug t(:no_current_release, host: host.to_s)
end
if directories.any?
directories_str = directories.map do |release|
releases_path.join(release)
end.join(" ")
directories_str = directories.join(" ")
execute :rm, "-rf", directories_str
else
info t(:no_old_releases, host: host.to_s, keep_releases: fetch(:keep_releases))