capistrano-pinned_releases 1.0.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 +7 -0
- data/.gitignore +9 -0
- data/.rubocop.yml +21 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +46 -0
- data/README.md +84 -0
- data/Rakefile +4 -0
- data/bin/setup +8 -0
- data/capistrano-pinned_releases.gemspec +44 -0
- data/lib/capistrano/pinned_releases.rb +11 -0
- data/lib/capistrano/pinned_releases/i18n.rb +9 -0
- data/lib/capistrano/pinned_releases/version.rb +7 -0
- data/lib/capistrano/tasks/deploy.rb +113 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e9eb06bbc1091855f3aa33d024cd4798b51a79d100cb3009ac7cf1e8e0fa409b
|
4
|
+
data.tar.gz: 21e59938678f9980b3d9dda91453310c98bc5e2af495167e2090d60a8654a54d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9a21f6c8ca0ea9aded3251312d47148ba62d2d5cef63483c6dd7b36d7984da31355b9b3f32a7003f9b396e1032b55a0bc41b5ee065ed08d5ad1acf28f03ceb6b
|
7
|
+
data.tar.gz: 09e708442c8c547be07091c1e75590a0fede7ed6880da5ff15e412c9e6e111dfc3b7b7db244f387a6d0330d71e883b7522b2dde290e02e8ca2c1651fc841cbc7
|
data/.gitignore
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.3.1
|
3
|
+
|
4
|
+
Style/StringLiterals:
|
5
|
+
EnforcedStyle: double_quotes
|
6
|
+
|
7
|
+
Style/HashSyntax:
|
8
|
+
EnforcedStyle: ruby19
|
9
|
+
|
10
|
+
Style/MultilineBlockChain:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Style/TrailingCommaInHashLiteral:
|
14
|
+
EnforcedStyleForMultiline: consistent_comma
|
15
|
+
|
16
|
+
Metrics/LineLength:
|
17
|
+
Max: 120
|
18
|
+
|
19
|
+
Metrics/BlockLength:
|
20
|
+
Exclude:
|
21
|
+
- lib/capistrano/tasks/deploy.rb
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
capistrano-pinned_releases (1.0.0)
|
5
|
+
capistrano (~> 3.4)
|
6
|
+
capistrano-bundler (~> 1.1)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
airbrussh (1.3.1)
|
12
|
+
sshkit (>= 1.6.1, != 1.7.0)
|
13
|
+
capistrano (3.11.0)
|
14
|
+
airbrussh (>= 1.0.0)
|
15
|
+
i18n
|
16
|
+
rake (>= 10.0.0)
|
17
|
+
sshkit (>= 1.9.0)
|
18
|
+
capistrano-bundler (1.5.0)
|
19
|
+
capistrano (~> 3.1)
|
20
|
+
coderay (1.1.2)
|
21
|
+
concurrent-ruby (1.1.4)
|
22
|
+
i18n (1.5.3)
|
23
|
+
concurrent-ruby (~> 1.0)
|
24
|
+
method_source (0.9.2)
|
25
|
+
net-scp (1.2.1)
|
26
|
+
net-ssh (>= 2.6.5)
|
27
|
+
net-ssh (5.1.0)
|
28
|
+
pry (0.12.2)
|
29
|
+
coderay (~> 1.1.0)
|
30
|
+
method_source (~> 0.9.0)
|
31
|
+
rake (10.5.0)
|
32
|
+
sshkit (1.18.2)
|
33
|
+
net-scp (>= 1.1.2)
|
34
|
+
net-ssh (>= 2.8.0)
|
35
|
+
|
36
|
+
PLATFORMS
|
37
|
+
ruby
|
38
|
+
|
39
|
+
DEPENDENCIES
|
40
|
+
bundler (~> 1.17)
|
41
|
+
capistrano-pinned_releases!
|
42
|
+
pry
|
43
|
+
rake (~> 10.0)
|
44
|
+
|
45
|
+
BUNDLED WITH
|
46
|
+
1.17.1
|
data/README.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# Capistrano: Pinned Releases
|
2
|
+
|
3
|
+
📌 Pin and unpin capistrano releases. Pinned releases don't get deleted during cleanup.
|
4
|
+
|
5
|
+
✋ **Capistrano 3.0+ only**.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'capistrano-pinned_releases'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle install
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install capistrano-pinned_releases
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
The extension provides following tasks, all under the `deploy:pinned` namespace.
|
26
|
+
|
27
|
+
1. **`list`**: List all currently pinned releases:
|
28
|
+
|
29
|
+
deploy:pinned:list
|
30
|
+
|
31
|
+
This prints a comma separated list of currently pinned releases:
|
32
|
+
|
33
|
+
** Execute deploy:pinned:list
|
34
|
+
20190220192205, 20190225190753
|
35
|
+
|
36
|
+
2. **`pin`**: Pin a given release:
|
37
|
+
|
38
|
+
cap production deploy:pinned:pin RELEASE_NAME=20190220192205
|
39
|
+
|
40
|
+
without the `RELEASE_NAME` environment variable, it pins the current release:
|
41
|
+
|
42
|
+
cap production deploy:pinned:pin
|
43
|
+
|
44
|
+
3. **`unpin`**: Unpin a given release:
|
45
|
+
|
46
|
+
deploy:pinned:unpin RELEASE_NAME=20190220192205
|
47
|
+
|
48
|
+
without the `RELEASE_NAME` environment variable, it pins the current release:
|
49
|
+
|
50
|
+
deploy:pinned:unpin
|
51
|
+
|
52
|
+
These tasks can be run individually, but they're far more useful when used during the capistrano release lifecycle:
|
53
|
+
|
54
|
+
after 'sidekiq:restart', 'deploy:pinned:pin'
|
55
|
+
|
56
|
+
Or, as a part of other tasks:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
rake my_task: :environment do
|
60
|
+
if capture(:some_command_on_server, :arg1, :arg2)
|
61
|
+
invoke 'deploy:pinned:pin'
|
62
|
+
else
|
63
|
+
invoke 'deploy:pinned:unpin'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# etc.
|
68
|
+
```
|
69
|
+
|
70
|
+
⚠️ This extension overrides the default `deploy:cleanup` task, in order to prevent releases from getting deployed. If you have an extension that also overrides the default behavior on `deploy:cleanup`, then this extension won't work for you. To work around, make sure you are not calling
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
Rake::Task["deploy:cleanup"].clear_actions
|
74
|
+
```
|
75
|
+
anywhere within your code.
|
76
|
+
|
77
|
+
|
78
|
+
## Development
|
79
|
+
|
80
|
+
Please fork your copy, and do all your work on a appropriately named branch. After checking out the repo, run `bin/setup` to install dependencies.
|
81
|
+
|
82
|
+
## Contributing
|
83
|
+
|
84
|
+
Bug reports and pull requests are welcome!
|
data/Rakefile
ADDED
data/bin/setup
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "capistrano/pinned_releases/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "capistrano-pinned_releases"
|
9
|
+
spec.version = Capistrano::PinnedReleases::VERSION
|
10
|
+
spec.authors = ["Swanand Pagnis"]
|
11
|
+
spec.email = ["swanand.pagnis@gmail.com"]
|
12
|
+
spec.summary = "Pin and unpin releases. Pinned releases are not deleted during cleanup"
|
13
|
+
spec.homepage = "https://github.com/swanandp/capistrano-pinned_releases"
|
14
|
+
|
15
|
+
spec.description = <<~TEXT
|
16
|
+
"Pin releases: Pin an arbitrary release and prevent it from getting deleted during `deploy:cleanup`.
|
17
|
+
Unpin the release to unprotect it"
|
18
|
+
TEXT
|
19
|
+
|
20
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
21
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
22
|
+
|
23
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes." unless spec.respond_to?(:metadata)
|
24
|
+
|
25
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
26
|
+
spec.metadata["source_code_uri"] = "https://github.com/swanandp/capistrano-pinned_releases"
|
27
|
+
spec.metadata["changelog_uri"] = "https://github.com/swanandp/capistrano-pinned_releases/blob/master/CHANGELOG.md"
|
28
|
+
|
29
|
+
# Specify which files should be added to the gem when it is released.
|
30
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
31
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
32
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
33
|
+
end
|
34
|
+
|
35
|
+
spec.bindir = "exe"
|
36
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
37
|
+
spec.require_paths = ["lib"]
|
38
|
+
|
39
|
+
spec.add_dependency "capistrano", "~> 3.4"
|
40
|
+
spec.add_dependency "capistrano-bundler", "~> 1.1"
|
41
|
+
|
42
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
43
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
44
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :deploy do
|
4
|
+
namespace :check do
|
5
|
+
desc "Check shared and release directories exist"
|
6
|
+
task :directories do
|
7
|
+
on release_roles :all do
|
8
|
+
execute :mkdir, "-p", deploy_path.join("pinned_releases")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
namespace :pinned do
|
14
|
+
# rubocop:disable Metrics/LineLength
|
15
|
+
desc "Pin a given release: 'cap production deploy:pin:release RELEASE_NAME=20190220192205', without RELEASE_NAME pins the current release"
|
16
|
+
# rubocop:enable Metrics/LineLength
|
17
|
+
task pin: "deploy:check" do
|
18
|
+
on release_roles :all do
|
19
|
+
release_name = ENV.fetch("RELEASE_NAME", "current")
|
20
|
+
releases_directory = deploy_path.join("releases")
|
21
|
+
pinned_releases_directory = deploy_path.join("pinned_releases")
|
22
|
+
|
23
|
+
if release_name == "current"
|
24
|
+
current_release_path = capture(:readlink, release_path.parent.join(current_path.basename))
|
25
|
+
current_release_name = capture(:basename, current_release_path)
|
26
|
+
|
27
|
+
pin_target = current_release_path
|
28
|
+
pin_name = pinned_releases_directory.join(current_release_name)
|
29
|
+
else
|
30
|
+
pin_target = releases_directory.join(release_name)
|
31
|
+
pin_name = pinned_releases_directory.join(release_name)
|
32
|
+
end
|
33
|
+
|
34
|
+
execute :ln, "-s", pin_target, pin_name
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# rubocop:disable Metrics/LineLength
|
39
|
+
desc "Unpin a given release: 'cap production deploy:pin:remove RELEASE_NAME=20190220192205', without RELEASE_NAME unpins the current release"
|
40
|
+
# rubocop:enable Metrics/LineLength
|
41
|
+
task unpin: "deploy:check" do
|
42
|
+
on release_roles :all do
|
43
|
+
release_name = ENV.fetch("RELEASE_NAME", "current")
|
44
|
+
pinned_releases_directory = deploy_path.join("pinned_releases")
|
45
|
+
|
46
|
+
if release_name == "current"
|
47
|
+
current_release_path = capture(:readlink, release_path.parent.join(current_path.basename))
|
48
|
+
current_release_name = capture(:basename, current_release_path)
|
49
|
+
|
50
|
+
pin_name = pinned_releases_directory.join(current_release_name)
|
51
|
+
else
|
52
|
+
pin_name = pinned_releases_directory.join(release_name)
|
53
|
+
end
|
54
|
+
|
55
|
+
execute :rm, "-f", pin_name
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
desc "List all currently pinned releases"
|
60
|
+
task list: "deploy:check" do
|
61
|
+
on release_roles :all do
|
62
|
+
pinned_releases_directory = deploy_path.join("pinned_releases")
|
63
|
+
pinned_releases = capture :ls, pinned_releases_directory
|
64
|
+
puts pinned_releases.split(/\s+/).sort.join(", ")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
desc "Clean up old releases"
|
70
|
+
Rake::Task["deploy:cleanup"].clear_actions
|
71
|
+
task cleanup: "check:directories" do
|
72
|
+
on release_roles :all do |host|
|
73
|
+
releases = capture(:ls, "-x", releases_path).split
|
74
|
+
valid, invalid = releases.partition { |e| /^\d{14}$/ =~ e }
|
75
|
+
|
76
|
+
warn t(:skip_cleanup, host: host.to_s) if invalid.any?
|
77
|
+
|
78
|
+
if valid.count >= fetch(:keep_releases)
|
79
|
+
info t(:keeping_releases, host: host.to_s, keep_releases: fetch(:keep_releases), releases: valid.count)
|
80
|
+
directories =
|
81
|
+
(valid - valid.last(fetch(:keep_releases))).map do |release|
|
82
|
+
releases_path.join(release).to_s
|
83
|
+
end.reject do |release|
|
84
|
+
release_name = capture(:basename, release)
|
85
|
+
|
86
|
+
if test("[ -d #{deploy_path.join('pinned_releases').join(release_name)} ]")
|
87
|
+
warn t(:wont_delete_pinned_release, host: host.to_s, release: release_name)
|
88
|
+
true
|
89
|
+
else
|
90
|
+
false
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
if test("[ -d #{current_path} ]")
|
95
|
+
current_release = capture(:readlink, current_path).to_s
|
96
|
+
|
97
|
+
if directories.include?(current_release)
|
98
|
+
warn t(:wont_delete_current_release, host: host.to_s)
|
99
|
+
directories.delete(current_release)
|
100
|
+
end
|
101
|
+
else
|
102
|
+
debug t(:no_current_release, host: host.to_s)
|
103
|
+
end
|
104
|
+
|
105
|
+
if directories.any?
|
106
|
+
execute :rm, "-rf", *directories
|
107
|
+
else
|
108
|
+
info t(:no_old_releases, host: host.to_s, keep_releases: fetch(:keep_releases))
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: capistrano-pinned_releases
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Swanand Pagnis
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-02-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: capistrano
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: capistrano-bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.17'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.17'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
description: |
|
70
|
+
"Pin releases: Pin an arbitrary release and prevent it from getting deleted during `deploy:cleanup`.
|
71
|
+
Unpin the release to unprotect it"
|
72
|
+
email:
|
73
|
+
- swanand.pagnis@gmail.com
|
74
|
+
executables: []
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files: []
|
77
|
+
files:
|
78
|
+
- ".gitignore"
|
79
|
+
- ".rubocop.yml"
|
80
|
+
- CHANGELOG.md
|
81
|
+
- Gemfile
|
82
|
+
- Gemfile.lock
|
83
|
+
- README.md
|
84
|
+
- Rakefile
|
85
|
+
- bin/setup
|
86
|
+
- capistrano-pinned_releases.gemspec
|
87
|
+
- lib/capistrano/pinned_releases.rb
|
88
|
+
- lib/capistrano/pinned_releases/i18n.rb
|
89
|
+
- lib/capistrano/pinned_releases/version.rb
|
90
|
+
- lib/capistrano/tasks/deploy.rb
|
91
|
+
homepage: https://github.com/swanandp/capistrano-pinned_releases
|
92
|
+
licenses: []
|
93
|
+
metadata:
|
94
|
+
homepage_uri: https://github.com/swanandp/capistrano-pinned_releases
|
95
|
+
source_code_uri: https://github.com/swanandp/capistrano-pinned_releases
|
96
|
+
changelog_uri: https://github.com/swanandp/capistrano-pinned_releases/blob/master/CHANGELOG.md
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.7.8
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: Pin and unpin releases. Pinned releases are not deleted during cleanup
|
117
|
+
test_files: []
|