kapost_deploy 0.1.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
+ 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: []