capistrano-pinned_releases 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ capistrano-pinned_releases-*.gem
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
@@ -0,0 +1,3 @@
1
+ # 1.0.0
2
+
3
+ Initial release
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in capistrano-pinned_releases.gemspec
8
+ gemspec
9
+
10
+ gem "pry"
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
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ task default: :spec
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -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,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "capistrano/pinned_releases/version"
4
+ require "capistrano/pinned_releases/i18n"
5
+ require "capistrano/tasks/deploy"
6
+
7
+ module Capistrano
8
+ # Your code goes here...
9
+ module PinnedReleases
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "i18n"
4
+
5
+ en = {
6
+ wont_delete_pinned_release: "The release '%{release}' is pinned; it won't be deleted from %{host}",
7
+ }
8
+
9
+ I18n.backend.store_translations(:en, capistrano: en)
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Capistrano
4
+ module PinnedReleases
5
+ VERSION = "1.0.0"
6
+ end
7
+ 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: []