kapost_deploy 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d8a0ed543f7bb6760e3719e3be2d7281ad9bc84b
4
- data.tar.gz: 0e78c6acf9e48f70a88f0650ba4ffaceef74aa29
3
+ metadata.gz: 465752e220872c86cf728e906b64fa82ff5ba691
4
+ data.tar.gz: 5592571df0b04754ce3ed7ba452d7defba8d6b3f
5
5
  SHA512:
6
- metadata.gz: 084d139d05b57f77a445b0928b5ec62671ede37718df3f72c31c4d082b4ebc252437361d9dd867871835d6b86d57e9ca3f2457db71f1c900d631184ccd2abf46
7
- data.tar.gz: 419a829ed7c06727ee931a65135e0597181435bb4736fcb01435cf7c9f05bd98d5ad9eb7fc87a6e94b329f22850a407d262aea234c981798dfb3195d90897069
6
+ metadata.gz: 34aa223ee90e83d688b15bacc6464ec20f9608ebd82b8a52e202ce4b491060c4b2fae5c8fb1090cd971f51d298e8f628158bdec4f398798cb7bfda8d1d973e58
7
+ data.tar.gz: 86b999a1120428691ae4bb0c6d660c64360e01cf21140d114275a4368c0c47d6b5b04053bff21c8f70489851a69200e5cab93665cf054bd22d18941b331a09f9
data/README.md CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  # Features
24
24
 
25
- `KapostDeploy::Task.new` creates the following rake tasks to aid in the pipeline promotion deployment of Heroku applications
25
+ `KapostDeploy::Task.define` creates the following rake tasks to aid in the pipeline promotion deployment of Heroku applications
26
26
 
27
27
  [promote]
28
28
  Promotes a source environment to production
@@ -35,11 +35,13 @@
35
35
 
36
36
  Simple Example:
37
37
 
38
- require 'kapost_deploy/task'
38
+ require "kapost_deploy/task"
39
39
 
40
- KapostDeploy::Task.new do |config|
41
- config.app = 'cabbage-democ'
42
- config.to = 'cabbage-prodc'
40
+ KapostDeploy::Task.define do |config|
41
+ config.app = "cabbage-staging"
42
+ config.to = "cabbage-production"
43
+ config.pipeline = "cabbage"
44
+ config.heroku_api_token = "123"
43
45
 
44
46
  config.after do
45
47
  puts "It's Miller time"
@@ -49,26 +51,56 @@ Simple Example:
49
51
  A slightly more complex example which will create 6 rake tasks: stage:before_stage, stage,
50
52
  stage:after_stage, promote:before_promote, promote, promote:after_promote
51
53
 
52
- KapostDeploy::Task.new(:stage) do |config|
53
- config.app = 'cabbage-stagingc'
54
- config.to = %w[cabbage-sandboxc cabbage-democ]
54
+ require "kapost_deploy/task"
55
+ require "kapost_deploy/plugins/slack_after_promote"
56
+ require "kapost_deploy/plugins/slack_github_diff"
57
+ require "kapost_deploy/plugins/db_migrate"
58
+
59
+ CONFIG = {
60
+ slack_config: {
61
+ webhook_url: "https://hooks.slack.com/services/34326/FDSJFH127/68357sdhfjhHSJGFNMDngsd",
62
+ channel: "#danger",
63
+ icon_url: "http://yourcompany.s3.amazonaws.com/logo.png"
64
+ },
65
+ git_config: {
66
+ github_repo: "yourcompany/widget"
67
+ }
68
+ }.freeze
69
+
70
+ KapostDeploy::Task.define(:stage) do |config|
71
+ config.app = "cabbage-staging"
72
+ config.to = "cabbage-sandbox"
73
+ config.pipeline = "cabbage"
74
+ config.heroku_api_token = "123"
75
+
76
+ config.options = CONFIG
55
77
 
56
78
  config.after do
57
79
  sleep 60*2 wait for dynos to restart
58
80
  slack.notify "The eagle has landed. [Go validate](https://testbed.sandbox.com/dashboard)!"
59
81
  Launchy.open("https://testbed.sandbox.com/dashboard")
60
82
  end
83
+
84
+ config.add_plugin(KapostDeploy::Plugins::DbMigrate)
61
85
  end
62
86
 
63
- KapostDeploy::Task.new(:promote) do |config|
64
- config.app = 'cabbage-sandbox1c'
65
- config.to = 'cabbage-prodc'
87
+ KapostDeploy::Task.define do |config|
88
+ config.app = "cabbage-sandboxc"
89
+ config.to = "cabbage-production"
90
+ config.pipeline = "cabbage"
91
+ config.heroku_api_token = "123"
92
+
93
+ config.options = CONFIG
66
94
 
67
95
  config.before do
68
- puts 'Are you sure you did x, y, and z? yes/no: '
96
+ puts "Are you sure you did x, y, and z? yes/no: "
69
97
  confirm = gets.strip
70
- exit(1) unless confirm.downcase == 'yes'
98
+ exit(1) unless confirm.downcase == "yes"
71
99
  end
100
+
101
+ config.add_plugin(KapostDeploy::Plugins::SlackGithubDiff)
102
+ config.add_plugin(KapostDeploy::Plugins::DbMigrate)
103
+ config.add_plugin(KapostDeploy::Plugins::SlackAfterPromote)
72
104
  end
73
105
 
74
106
  # Requirements
@@ -78,14 +110,19 @@ stage:after_stage, promote:before_promote, promote, promote:after_promote
78
110
 
79
111
  # Configuration Options
80
112
 
113
+ * `pipeline`: The application pipeline to promote
114
+ * `heroku_api_token`: Your platform api token. You can retrieve this using `heroku auth:token`
81
115
  * `app`: The application to be promoted
82
116
  * `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*
117
+ * `options`: An options hash containing plugin options:
118
+ * `git_config`: If using github plugins, an options hash containing the following keys:
119
+ * `github_repo`: The owner/repo string, such as `kapost/kapost_deploy`
120
+ * `slack_config`: If using slack plugins, an options hash containing the following keys:
121
+ * `webhook_url`: The webhook URL you added to your slack integrations
122
+ * `username`: The apparent username of the notifier *defaults to "webhooks bot"*
123
+ * `channel`: The channel name to post the notification to *defaults to "#general"*
124
+ * `icon_url`: A URL for the icon image *optional*
125
+ * `icon_emoji`: Emoji name to use instead of an icon *optional*
89
126
 
90
127
  # Setup
91
128
 
data/lib/kapost_deploy.rb CHANGED
@@ -1,4 +1,3 @@
1
1
  # frozen_string_literal: true
2
-
3
2
  require "kapost_deploy/identity"
4
3
  require "kapost_deploy/task"
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+ require "platform-api"
3
+
4
+ module KapostDeploy
5
+ module Heroku
6
+ # Promotes a heroku app via Heroku Plaform API
7
+ class AppPromoter
8
+ def initialize(pipeline, token:)
9
+ self.pipeline = pipeline
10
+ self.token = token
11
+ end
12
+
13
+ def promote(from:, to:)
14
+ pipeline_id = discover_pipeline(pipeline)["id"]
15
+ from_id = discover_app(from)["id"]
16
+ to_id = discover_app(to)["id"]
17
+
18
+ promotion_data = {
19
+ pipeline: { id: pipeline_id },
20
+ source: { app: { id: from_id } },
21
+ targets: [{ app: { id: to_id } }]
22
+ }
23
+
24
+ wait_for_promotion(heroku.pipeline_promotion.create(promotion_data))
25
+ end
26
+
27
+ private
28
+
29
+ attr_accessor :pipeline
30
+ attr_accessor :token
31
+
32
+ def wait_for_promotion(promotion)
33
+ while promotion["status"] == "pending"
34
+ print "."
35
+ sleep 1
36
+ promotion = heroku.pipeline_promotion.info(promotion["id"])
37
+ end
38
+ end
39
+
40
+ def discover_pipeline(pipeline)
41
+ heroku.pipeline.info(pipeline)
42
+ end
43
+
44
+ def discover_app(app_name)
45
+ heroku.app.info(app_name)
46
+ end
47
+
48
+ def heroku
49
+ @heroku ||= PlatformAPI.connect(token)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+ require "platform-api"
3
+
4
+ module KapostDeploy
5
+ module Heroku
6
+ # Promotes a heroku app via Heroku Plaform API
7
+ class AppReleases
8
+ def initialize(app, token:)
9
+ self.app = app
10
+ self.token = token
11
+ end
12
+
13
+ def latest_deploy_version
14
+ # This appears to be conventional for pipelines and standard heroku deploys and not a
15
+ # good way to get the deployed git version.
16
+ list.each do |item|
17
+ return Regexp.last_match[:sha1] if item["description"] =~ /^Deploy (?<sha1>[a-f0-9]+)$/
18
+ end
19
+ nil
20
+ end
21
+
22
+ def list
23
+ heroku.release.list(app)
24
+ end
25
+
26
+ private
27
+
28
+ attr_accessor :app
29
+ attr_accessor :token
30
+
31
+ def heroku
32
+ @heroku ||= PlatformAPI.connect(token, default_headers: { "Range" => "version ..; order=desc" })
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+ require "bundler"
3
+ require "English"
4
+
5
+ module KapostDeploy
6
+ module Heroku
7
+ # Wraps the heroku shell environment
8
+ # Derived from https://github.com/fastestforward/heroku_san
9
+ class Shell
10
+ def initialize(app)
11
+ self.app = app
12
+ end
13
+
14
+ def run(command)
15
+ sh("run " + command)
16
+ end
17
+
18
+ def sh(command)
19
+ preflight_check_for_cli
20
+
21
+ cmd = command.split(" ")
22
+ cmd += ["--app", app]
23
+ cmd << "--exit-code" if command =~ /^run/
24
+
25
+ show_command = cmd.join(" ")
26
+ ok = ::Bundler.with_clean_env { system "heroku", *cmd }
27
+
28
+ ok or fail "Command failed with status (#{$CHILD_STATUS.exitstatus}): [heroku #{show_command}]"
29
+ end
30
+
31
+ private
32
+
33
+ attr_accessor :app
34
+
35
+ def preflight_check_for_cli
36
+ if Bundler.with_clean_env { system("heroku version").nil? }
37
+ fail "The Heroku Toolbelt is required for this action. http://toolbelt.heroku.com"
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
-
3
2
  module KapostDeploy
4
3
  # Gem identity information.
5
4
  module Identity
@@ -12,7 +11,7 @@ module KapostDeploy
12
11
  end
13
12
 
14
13
  def self.version
15
- "0.1.1"
14
+ "0.2.0"
16
15
  end
17
16
 
18
17
  def self.version_label
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+ require "kapost_deploy/heroku/shell"
3
+
4
+ module KapostDeploy
5
+ module Plugins
6
+ # After-promotion task to run rake db:migrate
7
+ class DbMigrate
8
+ def initialize(config,
9
+ shell: KapostDeploy::Heroku::Shell.new(config.to))
10
+ self.shell = shell
11
+ end
12
+
13
+ def before
14
+ end
15
+
16
+ def after
17
+ shell.run("rake db:migrate")
18
+ end
19
+
20
+ private
21
+
22
+ attr_accessor :shell
23
+ end
24
+ end
25
+ end
@@ -1,11 +1,13 @@
1
- require "kapost_deploy/plugins/slack/notifier"
1
+ # frozen_string_literal: true
2
+ require "kapost_deploy/slack/notifier"
2
3
 
3
4
  module KapostDeploy
4
5
  module Plugins
5
6
  # After-promotion plugin to notify via slack after a promotion is complete with an
6
7
  # optional message.
7
8
  class SlackAfterPromote
8
- def initialize(config, notifier: Slack::Notifier.new(config.fetch(:slack_config, nil)))
9
+ def initialize(config,
10
+ notifier: KapostDeploy::Slack::Notifier.new(config.options.fetch(:slack_config, nil)))
9
11
  self.config = config
10
12
  self.notifier = notifier
11
13
  end
@@ -16,18 +18,29 @@ module KapostDeploy
16
18
  def after
17
19
  return unless notifier.configured?
18
20
 
19
- addl = slack_config.fetch(:additional_message, "")
20
- addl = "\n#{addl}" unless addl.empty?
21
-
22
- message = "#{identity} promoted *#{config.app}* to *#{config.to.join(",")}*#{addl}"
21
+ message = "#{identity} promoted *#{config.app}* to *#{config.to}*#{additional_message}"
23
22
  notifier.notify(message)
24
23
  end
25
24
 
26
25
  private
27
26
 
27
+ def additional_message
28
+ slack_config = config.options.fetch(:slack_config)
29
+ addl = ""
30
+ addl = slack_config.fetch(:additional_message, "") unless slack_config.nil?
31
+ addl = "\n#{addl}" unless addl.empty?
32
+ addl
33
+ end
34
+
35
+ def identity
36
+ @identity ||= `whoami`.chomp
37
+ end
38
+
28
39
  attr_accessor :notifier
29
40
 
30
41
  attr_accessor :config
42
+
43
+ attr_accessor :slack_config
31
44
  end
32
45
  end
33
46
  end
@@ -1,24 +1,31 @@
1
- require "kapost_deploy/plugins/slack/notifier"
2
- require "git"
1
+ # frozen_string_literal: true
2
+ require "kapost_deploy/slack/notifier"
3
+ require "kapost_deploy/heroku/app_releases"
3
4
 
4
5
  module KapostDeploy
5
6
  module Plugins
6
7
  # Before-promotion plugin to notify slack with a github comparison warning
7
8
  class SlackGithubDiff
8
- def initialize(config, notifier: Slack::Notifier.new(config.fetch(:slack_config, nil)))
9
- self.behind_app = config.to[0]
9
+ def initialize(config,
10
+ notifier: KapostDeploy::Slack::Notifier.new(config.options.fetch(:slack_config, nil)),
11
+ behind_releases: KapostDeploy::Heroku::AppReleases.new(config.to, token: config.heroku_api_token),
12
+ ahead_releases: KapostDeploy::Heroku::AppReleases.new(config.app, token: config.heroku_api_token))
13
+
10
14
  self.ahead_app = config.app
11
- self.github_config = config.fetch(:github_config, nil)
15
+ self.behind_app = config.to
16
+ self.git_config = config.options.fetch(:git_config, nil)
12
17
  self.notifier = notifier
18
+ self.behind_releases = behind_releases
19
+ self.ahead_releases = ahead_releases
13
20
  end
14
21
 
15
22
  def before
16
23
  return unless configured?
17
24
 
18
- count = commit_count(behind_sha1, ahead_sha1)
19
- link = github_compare_url(behind_sha1, ahead_sha1)
25
+ msg = "#{identity} is promoting <#{github_compare_url}|#{ahead_sha1}>"\
26
+ " from *#{ahead_app}* to *#{behind_app}*"
20
27
 
21
- notifier.notify("#{identity} is promoting #{count} commits to *#{config.to.join(",")}*: #{link}")
28
+ notifier.notify(msg)
22
29
  end
23
30
 
24
31
  def after
@@ -26,37 +33,31 @@ module KapostDeploy
26
33
 
27
34
  private
28
35
 
29
- def behind_sha1
30
- @behind_sha1 ||= heroku_head_sha1(behind_app)
31
- end
32
-
33
- def ahead_sha1
34
- @ahead_sha1 ||= heroku_head_sha1(ahead_app)
35
- end
36
-
37
36
  attr_accessor :notifier
38
- attr_accessor :github_config
39
- attr_accessor :behind_app
37
+ attr_accessor :git_config
38
+ attr_accessor :behind_releases
39
+ attr_accessor :ahead_releases
40
40
  attr_accessor :ahead_app
41
+ attr_accessor :behind_app
41
42
 
42
- def configured?
43
- !git_config.nil? && notifier.configured?
43
+ def behind_sha1
44
+ @behind_sha1 ||= behind_releases.latest_deploy_version
44
45
  end
45
46
 
46
- def heroku_head_sha1(app)
47
- Git.ls_remote("https://git.heroku.com/#{app}.git")["head"][:sha]
47
+ def ahead_sha1
48
+ @ahead_sha1 ||= ahead_releases.latest_deploy_version
48
49
  end
49
50
 
50
- def commit_count(behind_sha, ahead_sha)
51
- git.log.between(behind_sha, ahead_sha).size
51
+ def identity
52
+ @identity ||= `whoami`.chomp
52
53
  end
53
54
 
54
- def github_compare_url(behind_sha, ahead_sha)
55
- "https://github.com/#{github_config[:repo]}/compare/#{behind_sha}...#{ahead_sha}"
55
+ def configured?
56
+ !git_config.nil? && notifier.configured?
56
57
  end
57
58
 
58
- def git
59
- @git ||= Git.open(__dir__, log: Logger.new(STDOUT))
59
+ def github_compare_url
60
+ "https://github.com/#{git_config[:github_repo]}/compare/#{behind_sha1}...#{ahead_sha1}"
60
61
  end
61
62
  end
62
63
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+ require "slack-notify"
3
+
4
+ module KapostDeploy
5
+ module Slack
6
+ # Wrapper for slack-notify gem
7
+ class Notifier
8
+ def initialize(slack_config)
9
+ self.slack_config = slack_config
10
+ end
11
+
12
+ def notify(message)
13
+ return unless configured?
14
+ slack.notify(message)
15
+ end
16
+
17
+ def configured?
18
+ !slack_config.nil?
19
+ end
20
+
21
+ private
22
+
23
+ def slack
24
+ @slack ||= SlackNotify::Client.new(slack_config)
25
+ end
26
+
27
+ attr_accessor :slack_config
28
+ end
29
+ end
30
+ end
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
1
2
  require "rake"
2
3
  require "rake/tasklib"
3
- require "slack-notify"
4
+ require "kapost_deploy/heroku/app_promoter"
4
5
 
5
6
  module KapostDeploy
6
7
  ##
@@ -8,7 +9,9 @@ module KapostDeploy
8
9
  #
9
10
  # require 'kapost_deploy/task'
10
11
  #
11
- # KapostDeploy::Task.new do |config|
12
+ # KapostDeploy::Task.define do |config|
13
+ # config.pipeline = 'cabbage'
14
+ # config.heroku_api_token = ENV.fetch('HEROKU_API_TOKEN')
12
15
  # config.app = 'cabbage-democ'
13
16
  # config.to = 'cabbage-prodc'
14
17
  #
@@ -17,48 +20,27 @@ module KapostDeploy
17
20
  # end
18
21
  # end
19
22
  #
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
23
  class Task < Rake::TaskLib
45
24
  attr_accessor :app
46
25
 
47
- attr_reader :to
26
+ attr_accessor :to
27
+
28
+ attr_accessor :pipeline
29
+
30
+ attr_accessor :heroku_api_token
48
31
 
49
32
  attr_accessor :name
50
33
 
51
- attr_accessor :slack_config
34
+ attr_accessor :options
52
35
 
53
- def initialize(name = :promote, shell: method(:sh)) # :yield: self
54
- defaults
55
- @name = name
56
- @shell = shell
36
+ def self.define(name = :promote) # :yield: self
37
+ instance = new(name)
57
38
 
58
- yield self if block_given?
39
+ yield instance if block_given?
59
40
 
60
- validate
61
- define
41
+ instance.validate
42
+ instance.define
43
+ instance
62
44
  end
63
45
 
64
46
  def before(&block)
@@ -69,81 +51,78 @@ module KapostDeploy
69
51
  @after = block
70
52
  end
71
53
 
72
- def to=(to)
73
- @to = Array(to)
54
+ def add_plugin(plugin)
55
+ plugins << plugin
74
56
  end
75
57
 
76
58
  def defaults
77
59
  @name = :promote
60
+ @pipeline = nil
61
+ @heroku_api_token = nil
78
62
  @app = nil
79
- @slack_config = nil
80
- @to = []
63
+ @to = nil
81
64
  @before = -> {}
82
65
  @after = -> {}
66
+ @plugins = []
67
+ @options = {}
83
68
  end
84
69
 
85
70
  def validate
71
+ fail "No 'heroku_api_token' configured."\
72
+ "Set config.heroku_api_token to your API secret token" if heroku_api_token.nil?
73
+ fail "No 'pipeline' configured. Set config.pipeline to the name of your pipeline" if pipeline.nil?
86
74
  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?
75
+ fail "No 'to' configured. Set config.to to the downstream application to be promoted to" if to.nil?
88
76
  end
89
77
 
90
78
  def define
91
79
  define_hooks
92
80
 
93
- desc "Promote #{app} to #{to.join(",")}"
81
+ desc "Promote #{app} to #{to}"
94
82
  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
83
+ promote_with_hooks
100
84
  end
101
85
  end
102
86
 
103
87
  private
104
88
 
105
- def shell(command)
106
- @shell.call(command)
107
- end
108
-
109
- def pipelines_installed?
110
- `heroku plugins` =~ /^heroku-pipelines@/
89
+ def initialize(name)
90
+ defaults
91
+ self.name = name
111
92
  end
112
93
 
113
- def define_hooks
114
- namespace :"#{name}" do
115
- desc "Perform after-#{name} tasks"
116
- task :"after_#{name}" do
117
- @after.call
118
- end
94
+ attr_accessor :plugins
119
95
 
120
- desc "Perform before-#{name} tasks"
121
- task :"before_#{name}" do
122
- @before.call
123
- end
124
- end
96
+ def promoter
97
+ @promoter ||= KapostDeploy::Heroku::AppPromoter.new(pipeline, token: heroku_api_token)
125
98
  end
126
99
 
127
- def promote
128
- shell("heroku pipelines:promote -a #{app} --to #{to.join(",")}")
100
+ def promote_with_hooks
101
+ Rake.application[:"#{name}:before_#{name}"].execute
102
+ promoter.promote(from: app, to: to)
103
+ Rake.application[:"#{name}:after_#{name}"].execute
129
104
  end
130
105
 
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)
106
+ def shell(command)
107
+ @shell.call(command)
139
108
  end
140
109
 
141
- def identity
142
- @identity ||= `whoami`.chomp
110
+ def define_hooks
111
+ namespace :"#{name}" do
112
+ define_hook(:before)
113
+ define_hook(:after)
114
+ end
143
115
  end
144
116
 
145
- def slack
146
- @slack ||= SlackNotify::Client.new(slack_config)
117
+ def define_hook(kind)
118
+ desc "Perform #{kind}-#{name} tasks"
119
+ task :"#{kind}_#{name}" do
120
+ instance_variable_get(:"@#{kind}").call
121
+ plugins.each do |p|
122
+ plugin = p.new(self)
123
+ plugin.send(kind) if plugin.respond_to?(kind)
124
+ end
125
+ end
147
126
  end
148
127
  end
149
128
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  desc "Open IRB console for gem development environment"
2
3
  task :console do
3
4
  require "irb"
data/lib/tasks/rspec.rake CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  begin
2
3
  require "rspec/core/rake_task"
3
4
  RSpec::Core::RakeTask.new(:spec)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  begin
2
3
  require "rubocop/rake_task"
3
4
  RuboCop::RakeTask.new
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kapost_deploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Croft
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-29 00:00:00.000000000 Z
11
+ date: 2016-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -25,31 +25,31 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '10.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: heroku
28
+ name: platform-api
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '3.43'
33
+ version: 0.6.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '3.43'
40
+ version: 0.6.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: slack-notify
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 0.4.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: 0.4.1
55
55
  - !ruby/object:Gem::Dependency
@@ -272,10 +272,14 @@ extra_rdoc_files:
272
272
  files:
273
273
  - README.md
274
274
  - lib/kapost_deploy.rb
275
+ - lib/kapost_deploy/heroku/app_promoter.rb
276
+ - lib/kapost_deploy/heroku/app_releases.rb
277
+ - lib/kapost_deploy/heroku/shell.rb
275
278
  - lib/kapost_deploy/identity.rb
276
- - lib/kapost_deploy/plugins/slack/notifier.rb
279
+ - lib/kapost_deploy/plugins/db_migrate.rb
277
280
  - lib/kapost_deploy/plugins/slack_after_promote.rb
278
281
  - lib/kapost_deploy/plugins/slack_github_diff.rb
282
+ - lib/kapost_deploy/slack/notifier.rb
279
283
  - lib/kapost_deploy/task.rb
280
284
  - lib/tasks/console.rake
281
285
  - lib/tasks/rspec.rake
@@ -1,35 +0,0 @@
1
- require "slack-notify"
2
-
3
- module KapostDeploy
4
- module Plugins
5
- module Slack
6
- # Wrapper for slack-notify gem
7
- class Notifier
8
- def initialize(slack_config)
9
- self.slack_config = slack_config
10
- end
11
-
12
- def notify_slack(message)
13
- return unless configured?
14
- slack.notify(message)
15
- end
16
-
17
- def identity
18
- @identity ||= `whoami`.chomp
19
- end
20
-
21
- def configured?
22
- !slack_config.nil?
23
- end
24
-
25
- private
26
-
27
- def slack
28
- @slack ||= SlackNotify::Client.new(slack_config)
29
- end
30
-
31
- attr_accessor :slack_config
32
- end
33
- end
34
- end
35
- end