kapost_deploy 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 874289c8439280011dfee2c03331c8ae4d840743
4
+ data.tar.gz: 26db5e6fcbaf0844b68a1dd5e6ca78fc9cc0c6ea
5
+ SHA512:
6
+ metadata.gz: e5eee4543078317ce1e784a4665214b1881cc96cf0669d6c8d6ba84f4af6dfedc86f697fab6a925b6194d2e4443e71075aa2be8417d3afb6f04d53c24d9fccbe
7
+ data.tar.gz: d21e42e8e46b8431fbb2949818157eb4cb08328b2b0c8245835ed71d294756def0e07c7bd8652b3d56f85e01d75c32486a8a84f90f98f5e835ea95a93fe676c2
data/README.md ADDED
@@ -0,0 +1,134 @@
1
+ # KapostDeploy
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/kapost_deploy.svg)](http://badge.fury.io/rb/kapost_deploy)
4
+ [![Code Climate GPA](https://codeclimate.com/github/kapost/kapost_deploy.svg)](https://codeclimate.com/github/kapost/kapost_deploy)
5
+ [![Code Climate Coverage](https://codeclimate.com/github/kapost/kapost_deploy/coverage.svg)](https://codeclimate.com/github/kapost/kapost_deploy)
6
+
7
+ <!-- Tocer[start]: Auto-generated, don't remove. -->
8
+
9
+ # Table of Contents
10
+
11
+ - [Features](#features)
12
+ - [Requirements](#requirements)
13
+ - [Setup](#setup)
14
+ - [Tests](#tests)
15
+ - [Versioning](#versioning)
16
+ - [Contributions](#contributions)
17
+ - [License](#license)
18
+ - [History](#history)
19
+ - [Credits](#credits)
20
+
21
+ <!-- Tocer[finish]: Auto-generated, don't remove. -->
22
+
23
+ # Features
24
+
25
+ `KapostDeploy::Task.new` creates the following rake tasks to aid in the pipeline promotion deployment of Heroku applications
26
+
27
+ [promote]
28
+ Promotes a source environment to production
29
+
30
+ [promote:before_promote]
31
+ Executes application-defined before promotion code as defined in task config (See below)
32
+
33
+ [promote:after_promote]
34
+ Executes application-defined after promotion code as defined in task config (See below)
35
+
36
+ Simple Example:
37
+
38
+ require 'kapost_deploy/task'
39
+
40
+ KapostDeploy::Task.new do |config|
41
+ config.app = 'cabbage-democ'
42
+ config.to = 'cabbage-prodc'
43
+
44
+ config.after do
45
+ puts "It's Miller time"
46
+ end
47
+ end
48
+
49
+ A slightly more complex example which will create 6 rake tasks: stage:before_stage, stage,
50
+ stage:after_stage, promote:before_promote, promote, promote:after_promote
51
+
52
+ KapostDeploy::Task.new(:stage) do |config|
53
+ config.app = 'cabbage-stagingc'
54
+ config.to = %w[cabbage-sandboxc cabbage-democ]
55
+
56
+ config.after do
57
+ sleep 60*2 wait for dynos to restart
58
+ slack.notify "The eagle has landed. [Go validate](https://testbed.sandbox.com/dashboard)!"
59
+ Launchy.open("https://testbed.sandbox.com/dashboard")
60
+ end
61
+ end
62
+
63
+ KapostDeploy::Task.new(:promote) do |config|
64
+ config.app = 'cabbage-sandbox1c'
65
+ config.to = 'cabbage-prodc'
66
+
67
+ config.before do
68
+ puts 'Are you sure you did x, y, and z? yes/no: '
69
+ confirm = gets.strip
70
+ exit(1) unless confirm.downcase == 'yes'
71
+ end
72
+ end
73
+
74
+ # Requirements
75
+
76
+ 0. [MRI 2.3.0](https://www.ruby-lang.org)
77
+ 0. [Heroku Toolbelt](https://github.com/heroku/heroku) installed
78
+
79
+ # Configuration Options
80
+
81
+ * `app`: The application to be promoted
82
+ * `to`: The downstream application(s) to receive the promotion. For multiple environments, use an array.
83
+ * `slack_config`: An options hash containing the following keys:
84
+ * `webhook_url`: The webhook URL you added to your slack integrations
85
+ * `username`: The apparent username of the notifier *defaults to "webhooks bot"*
86
+ * `channel`: The channel name to post the notification to *defaults to "#general"*
87
+ * `icon_url`: A URL for the icon image *optional*
88
+ * `icon_emoji`: Emoji name to use instead of an icon *optional*
89
+
90
+ # Setup
91
+
92
+ To install, type the following:
93
+
94
+ gem install kapost_deploy
95
+
96
+ Add the following to your Gemfile:
97
+
98
+ gem "kapost_deploy"
99
+
100
+ # Tests
101
+
102
+ To test, run:
103
+
104
+ bundle exec rake
105
+
106
+ # Versioning
107
+
108
+ Read [Semantic Versioning](http://semver.org) for details. Briefly, it means:
109
+
110
+ - Patch (x.y.Z) - Incremented for small, backwards compatible bug fixes.
111
+ - Minor (x.Y.z) - Incremented for new, backwards compatible public API enhancements and/or bug fixes.
112
+ - Major (X.y.z) - Incremented for any backwards incompatible public API changes.
113
+
114
+ # Contributions
115
+
116
+ Fork the project.
117
+ Make your feature addition or bug fix.
118
+ Do not bump the version number.
119
+ Send me a pull request. Bonus points for topic branches.
120
+
121
+ # License
122
+
123
+ MIT
124
+
125
+ Copyright (c) 2016 [Kapost](http://engineering.kapost.com).
126
+
127
+ # History
128
+
129
+ Read the [CHANGELOG](CHANGELOG.md) for details.
130
+ Built with [Gemsmith](https://github.com/bkuhlmann/gemsmith).
131
+
132
+ # Credits
133
+
134
+ Developed by [Brandon Croft](http://brandoncroft.com) at [brandon@kapost.com](mailto:brandon@kapost.com).
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "kapost_deploy/identity"
4
+ require "kapost_deploy/task"
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module KapostDeploy
4
+ # Gem identity information.
5
+ module Identity
6
+ def self.name
7
+ "kapost_deploy"
8
+ end
9
+
10
+ def self.label
11
+ "KapostDeploy"
12
+ end
13
+
14
+ def self.version
15
+ "0.1.0"
16
+ end
17
+
18
+ def self.version_label
19
+ "#{label} #{version}"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,149 @@
1
+ require "rake"
2
+ require "rake/tasklib"
3
+ require "slack-notify"
4
+
5
+ module KapostDeploy
6
+ ##
7
+ # Simple Example:
8
+ #
9
+ # require 'kapost_deploy/task'
10
+ #
11
+ # KapostDeploy::Task.new do |config|
12
+ # config.app = 'cabbage-democ'
13
+ # config.to = 'cabbage-prodc'
14
+ #
15
+ # config.after do
16
+ # puts "It's Miller time"
17
+ # end
18
+ # end
19
+ #
20
+ # A slightly more complex example which will create 6 rake tasks: before_stage, stage,
21
+ # after_stage, before_promote, promote, after_promote
22
+ #
23
+ # KapostDeploy::Task.new(:stage) do |config|
24
+ # config.app = 'cabbage-stagingc'
25
+ # config.to = %w[cabbage-sandboxc cabbage-democ]
26
+ #
27
+ # config.after do
28
+ # sleep 60*2 # wait for dynos to restart
29
+ # notifier.ping "The eagle has landed. [Go validate](https://testbed.sandbox.com/dashboard)!"
30
+ # Launchy.open("https://testbed.sandbox.com/dashboard")
31
+ # end
32
+ # end
33
+ #
34
+ # KapostDeploy::Task.new(:promote) do |config|
35
+ # config.app = 'cabbage-sandbox1c'
36
+ # config.to = 'cabbage-prodc'
37
+ #
38
+ # config.before do
39
+ # puts 'Are you sure you did x, y, and z? yes/no: '
40
+ # confirm = gets.strip
41
+ # exit(1) unless confirm.downcase == 'yes'
42
+ # end
43
+ # end
44
+ class Task < Rake::TaskLib
45
+ attr_accessor :app
46
+
47
+ attr_reader :to
48
+
49
+ attr_accessor :name
50
+
51
+ attr_accessor :slack_config
52
+
53
+ def initialize(name = :promote, shell: method(:sh)) # :yield: self
54
+ defaults
55
+ @name = name
56
+ @shell = shell
57
+
58
+ yield self if block_given?
59
+
60
+ validate
61
+ define
62
+ end
63
+
64
+ def before(&block)
65
+ @before = block
66
+ end
67
+
68
+ def after(&block)
69
+ @after = block
70
+ end
71
+
72
+ def to=(to)
73
+ @to = Array(to)
74
+ end
75
+
76
+ def defaults
77
+ @name = :promote
78
+ @app = nil
79
+ @slack_config = nil
80
+ @to = []
81
+ @before = -> {}
82
+ @after = -> {}
83
+ end
84
+
85
+ def validate
86
+ fail "No 'app' configured. Set config.app to the application to be promoted" if app.nil?
87
+ fail "No 'to' configured. Set config.to to the downstream application(s) to be promoted to" if to.empty?
88
+ end
89
+
90
+ def define
91
+ define_hooks
92
+
93
+ desc "Promote #{app} to #{to.join(",")}"
94
+ task name.to_s do
95
+ shell("heroku plugins:install heroku-pipelines") unless pipelines_installed?
96
+ @before.call
97
+ promote
98
+ notify_slack
99
+ @after.call
100
+ end
101
+ end
102
+
103
+ private
104
+
105
+ def shell(command)
106
+ @shell.call(command)
107
+ end
108
+
109
+ def pipelines_installed?
110
+ `heroku plugins` =~ /^heroku-pipelines@/
111
+ end
112
+
113
+ def define_hooks
114
+ namespace :"#{name}" do
115
+ desc "Perform after-#{name} tasks"
116
+ task :"after_#{name}" do
117
+ @after.call
118
+ end
119
+
120
+ desc "Perform before-#{name} tasks"
121
+ task :"before_#{name}" do
122
+ @before.call
123
+ end
124
+ end
125
+ end
126
+
127
+ def promote
128
+ shell("heroku pipelines:promote -a #{app} --to #{to.join(",")}")
129
+ end
130
+
131
+ def notify_slack
132
+ return unless slack_config
133
+
134
+ addl = slack_config.fetch(:additional_message, "")
135
+ addl = "\n#{addl}" unless addl.empty?
136
+
137
+ message = "#{identity} promoted *#{app}* to *#{to.join(",")}*#{addl}"
138
+ slack.notify(message)
139
+ end
140
+
141
+ def identity
142
+ @identity ||= `whoami`.chomp
143
+ end
144
+
145
+ def slack
146
+ @slack ||= SlackNotify::Client.new(slack_config)
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,7 @@
1
+ desc "Open IRB console for gem development environment"
2
+ task :console do
3
+ require "irb"
4
+ require "kapost_deploy"
5
+ ARGV.clear
6
+ IRB.start
7
+ end
@@ -0,0 +1,6 @@
1
+ begin
2
+ require "rspec/core/rake_task"
3
+ RSpec::Core::RakeTask.new(:spec)
4
+ rescue LoadError => error
5
+ puts error.message
6
+ end
@@ -0,0 +1,6 @@
1
+ begin
2
+ require "rubocop/rake_task"
3
+ RuboCop::RakeTask.new
4
+ rescue LoadError => error
5
+ puts error.message
6
+ end
metadata ADDED
@@ -0,0 +1,304 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kapost_deploy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Brandon Croft
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-04-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '10.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '10.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: heroku
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.43'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.43'
41
+ - !ruby/object:Gem::Dependency
42
+ name: slack-notify
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.4.1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.4.1
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.11'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.11'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry-remote
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pry-state
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry-rescue
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: pry-stack_explorer
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rspec
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '3.4'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '3.4'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rb-fsevent
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: guard-rspec
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: terminal-notifier
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: terminal-notifier-guard
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ - !ruby/object:Gem::Dependency
224
+ name: rubocop
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: '0.37'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: '0.37'
237
+ - !ruby/object:Gem::Dependency
238
+ name: codeclimate-test-reporter
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
251
+ - !ruby/object:Gem::Dependency
252
+ name: rubygems-tasks
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - ">="
256
+ - !ruby/object:Gem::Version
257
+ version: '0'
258
+ type: :development
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - ">="
263
+ - !ruby/object:Gem::Version
264
+ version: '0'
265
+ description: Execute deployments swiftly and safely using `rake promote`
266
+ email:
267
+ - brandon.croft@gmail.com
268
+ executables: []
269
+ extensions: []
270
+ extra_rdoc_files:
271
+ - README.md
272
+ files:
273
+ - README.md
274
+ - lib/kapost_deploy.rb
275
+ - lib/kapost_deploy/identity.rb
276
+ - lib/kapost_deploy/task.rb
277
+ - lib/tasks/console.rake
278
+ - lib/tasks/rspec.rake
279
+ - lib/tasks/rubocop.rake
280
+ homepage: https://github.com/kapost/kapost_deploy
281
+ licenses:
282
+ - MIT
283
+ metadata: {}
284
+ post_install_message:
285
+ rdoc_options: []
286
+ require_paths:
287
+ - lib
288
+ required_ruby_version: !ruby/object:Gem::Requirement
289
+ requirements:
290
+ - - ">="
291
+ - !ruby/object:Gem::Version
292
+ version: '0'
293
+ required_rubygems_version: !ruby/object:Gem::Requirement
294
+ requirements:
295
+ - - ">="
296
+ - !ruby/object:Gem::Version
297
+ version: '0'
298
+ requirements: []
299
+ rubyforge_project:
300
+ rubygems_version: 2.5.1
301
+ signing_key:
302
+ specification_version: 4
303
+ summary: Deployment rake tasks for Kapost applications
304
+ test_files: []