capistrano-mailgun 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,30 @@
1
+ ## 2012-10-?? - v1.1.0
2
+ * default subject now includes stage
3
+ * built-in templates
4
+ * support for custom messages
5
+
6
+ ## 2012-10-15 - v1.0.2
7
+ * Minor release
8
+ * documentation changes
9
+
10
+ ## 2012-10-15 - v1.0.1
11
+ * Minor release
12
+ * documentation changes
13
+
14
+ ## 2012-10-15 - v1.0.0
15
+ * Version 1.0.0!
16
+ * Proper definitions of dependencies
17
+ * Proper documentation
18
+ * Full support for Mailgun API options in `mailgun.send_email`
19
+ * Deduplication of email addresses in `mailgun.build_recipients`
20
+ * Support for custom domain in `mailgun.build_recipients`
21
+ * Support for HTML and text templates in emails using `mailgun.notify_of_deploy`
22
+ * Full rspec test suite
23
+
24
+ ## 2012-10-11 - v0.1.1
25
+
26
+ * Fixed a bug where it would blow up if you `require` the gem inside a non-Capistrano environment
27
+
28
+ ## 2012-10-11 - v0.1.0
29
+
30
+ Initial Release
data/README.md CHANGED
@@ -1,11 +1,12 @@
1
- # Capistrano-Mailgun [![Build Status](https://travis-ci.org/spikegrobstein/capistrano-mailgun.png)](https://travis-ci.org/spikegrobstein/capistrano-mailgun)
1
+ # Capistrano::Mailgun [![Build Status](https://travis-ci.org/spikegrobstein/capistrano-mailgun.png)](https://travis-ci.org/spikegrobstein/capistrano-mailgun)
2
2
 
3
3
  *Bust a cap in your deployment notifications*
4
4
 
5
- Send emails with erb template bodies easily from inside your capistrano recipes.
5
+ Mailgun.org is an excellent, API-driven email provider. So, bust out your nine, pop in the clip and send emails
6
+ easily from inside your Capistrano recipes.
6
7
 
7
- Although built primarily for sending notification emails of deploys, it also includes nice helper methods
8
- for sending any kind of email via the Mailgun API.
8
+ `Capistrano::Mailgun` provides a simple interface for notifying of deploys, exposing your Capistrano
9
+ variables to your ERB template built on top of a more robust public interface to the Mailgun API.
9
10
 
10
11
  ## Installation
11
12
 
@@ -34,18 +35,14 @@ To send a notification after deploy, add the following to your `deploy.rb` file:
34
35
  set :mailgun_from, 'deployment@example.com' # who the email will appear to come from
35
36
  set :mailgun_recipients, [ 'you@example.com', 'otherguy@example.com' ] # who will receive the email
36
37
 
37
- # The erb template will have visibility into all your capistrano variables.
38
- # this template will be the text body of the notification email
39
- set :mailgun_text_template, File.join(File.dirname(__FILE__), 'mail.erb')
40
-
41
38
  # create an after deploy hook
42
- after(:deploy) { mailgun.notify_of_deploy }
43
-
44
- You should then create a `mail.erb` file in the same directory as `deploy.rb`:
39
+ after :deploy, 'mailgun_notify'
45
40
 
46
- <%= application %> has just been deployed by <%= deployer_name %>, yay!
41
+ That's it. When you do a deploy, it should automatically send an email using the built-in text and HTML
42
+ templates.
47
43
 
48
- That's it. When you do a deploy, it should automatically send an email.
44
+ `Capistrano::Mailgun` defines a `mailgun_notify` task which calls the `mailgun.notify_of_deploy` function,
45
+ using your Capistrano configuration to send the notification.
49
46
 
50
47
  ## Example using mailgun.send_email
51
48
 
@@ -57,6 +54,8 @@ in your `deploy.rb` file:
57
54
  set :mailgun_api_key, 'key-12345678901234567890123456789012' # your mailgun API key
58
55
  set :mailgun_domain, 'example.com' # your mailgun email domain
59
56
 
57
+ set :mailgun_recipient_domain, 'example.com' # append this to any unqualified email addresses
58
+
60
59
  set(:email_body) { abort "Please set email_body using `-s email_body='this is the body of the email'" }
61
60
 
62
61
  # some variables that we'll use when calling mailgun.send_email
@@ -67,7 +66,7 @@ in your `deploy.rb` file:
67
66
  namespace :email do
68
67
  task :ops do
69
68
  mailgun.send_email(
70
- :to => mailgun.build_recipients(ops_emails, 'example.com'), # use build_recipients to format TO field properly
69
+ :to => ops_emails, # build_recipients gets called automatically by Capistrano::Mailgun
71
70
  :from => 'some_dude@example.com',
72
71
  :subject => 'you have just been mailgunned',
73
72
  :text => email_body
@@ -78,7 +77,7 @@ in your `deploy.rb` file:
78
77
  mailgun.send_email(
79
78
  :to => 'no-reply@example.com',
80
79
  :from => 'no-reply@example.com',
81
- :bcc => mailgun.build_recipients(dev_emails, 'example.com'),
80
+ :bcc => mailgun.build_recipients(dev_emails, 'audit.example.com'), # note the different domain
82
81
  :subject => 'You guys are just developers',
83
82
  :text => email_body
84
83
  )
@@ -98,7 +97,7 @@ Also, notice the use of `mailgun.build_recipients`. See documentation below for
98
97
 
99
98
  ## Capistrano Variables
100
99
 
101
- `capistrano-mailgun` leverages variables defined in Capistrano to reduce the amount of configuration
100
+ `Capistrano::Mailgun` leverages variables defined in Capistrano to reduce the amount of configuration
102
101
  you need to do. The following are all variables it supports:
103
102
 
104
103
  ### mailgun_api_key (required)
@@ -115,55 +114,124 @@ The email address that your notifications will appear to come from (by default).
115
114
 
116
115
  ### mailgun_recipients (required for notify_of_deploy)
117
116
 
118
- An array of email addresses who should recieve a notification when a deployment completes.
117
+ The email address as a string or an array of email addresses who should recieve an email from `notify_of_deploy`.
119
118
 
120
- You can optionally only specify just the part of the email address before the @ and `capistrano-mailgun` will
119
+ You can optionally only specify just the part of the email address before the @ and `Capistrano::Mailgun` will
121
120
  automatically append the `mailgun_recipient_domain` to it. See `mailgun_recipient_domain`.
122
121
 
122
+ If you omit the domain and don't specify `mailgun_recipient_domain`, a error will be raised.
123
+
124
+ ### mailgun_cc
125
+
126
+ An array of email addresses who should be CC'd when `mailgun.notify_of_deploy` is called. This will
127
+ follow the same rules as the `mailgun_recipients` variable with respect to the handling of unqualified
128
+ email addresses.
129
+
130
+ ### mailgun_bcc
131
+
132
+ An array of email addresses who should be BCC'd when `mailgun.notify_of_deploy` is called. This will
133
+ follow the same rules as the `mailgun_recipients` variable with respect to the handling of unqualified
134
+ eail addresses.
135
+
123
136
  ### mailgun_text_template (required for notify_of_deploy)
124
137
 
125
- This is the path to the ERB template that `Capistrano::Mailgun` will use to create the text body of
138
+ This is the path to the ERB template that `mailgun.notify_of_deploy` will use to create the text body of
126
139
  your email. This is only required if you do not use the `mailgun_html_template` variable. You can
127
140
  specify both text and html templates and the emails will contain the proper bodies where the client
128
141
  supports it.
129
142
 
143
+ The default setting for this is `:deploy_text` which is a built-in template. See "Built-in Templates"
144
+ below for more information.
145
+
130
146
  ### mailgun_html_template (required for notify_of_deploy)
131
147
 
132
148
  This is the path to the ERB template that will be used to generate the HTML body of the email. It is only
133
149
  required if you do not specify the `mailgun_text_template` variable. You can specify both text and html
134
150
  templates and emails will contain the proper bodies where the client supports it.
135
151
 
152
+ The default setting for this is `:deploy_html` which is a built-in template. See "Built-in Templates"
153
+ below for more information.
154
+
136
155
  ### mailgun_recipient_domain
137
156
 
138
157
  The domain that will be automatically appended to incomplete email addresses in the `mailgun_recipients`.
139
158
 
159
+ Example:
160
+
161
+ set :mailgun_recipient_domain, 'example.com'
162
+ set :mailgun_recipients, [ 'alice', 'bob', 'carl@contractors.net' ]
163
+
164
+ When an email is sent from `Capistrano::Mailgun`, the recipients will be processed and the email will be sent to:
165
+
166
+ * alice@example.com
167
+ * bob@example.com
168
+ * carl@contractors.net
169
+
170
+ If `mailgun_recipient_domain` is not set, `Capistrano::Mailgun` will raise an error.
171
+
140
172
  ### mailgun_subject
141
173
 
142
174
  The subject to be used in deployment emails. This defaults to:
143
175
 
144
- [Deployment] #{ application.capitalize } complete
176
+ [Deployment] #{ application.capitalize } deploy completed
177
+
178
+ In the event that you're using multistage, it will include that:
179
+
180
+ [Deployment] #{ stage.capitalize } #{ application.capitalize } deploy completed
181
+
182
+ Setting this variable yourself will override the default.
183
+
184
+ ### mailgun_message
185
+
186
+ An optional message can be specified to be included in the email. This is used inside the default templates,
187
+ so if you use your own templates, you'll have to include support for this variable yourself.
145
188
 
146
- Setting this will override the default.
189
+ The purpose of this variable is to be set when calling capistrano so you can have a custom, per-deploy message.
190
+ You would call it in the following manner:
191
+
192
+ cap deploy -s mailgun_message="Fixes that really nasty bug where our site does not work"
193
+
194
+ ### github_url
195
+
196
+ If your project is hosted on Github and you'd like to have links to the Github repository in the deployment
197
+ notifications, set this. It should be in the following format:
198
+
199
+ https://github.com/USERNAME/PROJECT
200
+
201
+ This is used for linking to commits from the log and linking to the Github page for the exact revision that
202
+ was deployed.
203
+
204
+ ## Capistrano Tasks
205
+
206
+ ### mailgun_notify
207
+
208
+ This task is defined strictly for convenience in defining Capistrano hooks and for sending a notification
209
+ from the commandline. All it does is run `mailgun.notify_of_deploy` on your local machine.
210
+
211
+ Normally, you'd want to have an after-hook on `deploy` defined as follows:
212
+
213
+ after :deploy, 'mailgun_notify'
147
214
 
148
215
  ## Function API
149
216
 
150
- `capistrano-mailgun` has a couple of methods to enable you to send emails easily. The following are the functions:
217
+ `Capistrano::Mailgun` has a couple of functions to simplify some common tasks. The following are the functions:
151
218
 
152
219
  ### mailgun.build_recipients( recipients, default_domain=nil )
153
220
 
154
221
  Given an array of email addresses, this will join them with a comma so any recipients field with more than 1 recipient
155
- will be formatted properly, have the recipients list deduplicated and returned as a string. Typically, you will only use
156
- this function in the event that you're calling `mailgun.send_email` directly.
222
+ will be formatted properly, have the recipients list deduplicated and returned as a string. Typically, you will not call
223
+ this function directly as `Capistrano::Mailgun` calls it implicitely on your `to`, `cc` and `bcc` fields before hitting
224
+ the Mailgun API.
157
225
 
158
226
  You can also pass an alternate `default_domain`. This is useful if you're not using the global `mailgun_recipient_domain`
159
- Capistrano variable of if you want to override the behavior in this one use-case. `mailgun.build_recipients` will always
160
- choose the specified `default_domain` over `mailgun_recipient_domain`.
227
+ Capistrano variable of if you want to override the behavior in a specific case. `mailgun.build_recipients` will always
228
+ choose the specified `default_domain` passed to the function over the Capistrano variable `mailgun_recipient_domain`.
161
229
 
162
230
  ### mailgun.notify_of_deploy
163
231
 
164
- This is a convenience function to send an email via the Mailgun api using your Capistrano variables for
165
- basic configuration. It will use either/or `mailgun_html_template` and `mailgun_text_template` to generate the
166
- email body, `mailgun_recipients` for who to address the email to, `mailgun_from` for the reply-to field
232
+ This is a convenience function to send an email via the Mailgun api using your Capistrano variables for declarative
233
+ configuration. It will use `mailgun_html_template` and `mailgun_text_template` to generate the email body when set,
234
+ `mailgun_recipients` for who to address the email to, `mailgun_from` for the reply-to field
167
235
  of the email and `mailgun_subject` for the subject of the email.
168
236
 
169
237
  See Quickstart, above, for an example.
@@ -182,9 +250,13 @@ This function also takes the following additional options:
182
250
  * `:text_template` -- a path to an ERB template for the text body of the email.
183
251
  * `:html_template` -- a path to an ERB template for the HTML body of the email.
184
252
 
185
- The templates will have access to all of your Capistrano variables.
253
+ The templates will have access to all of your Capistrano variables and anything else that Capistrano can see
254
+ such as methods and Capistrano plugins (including `Capistrano::Mailgun`).
186
255
 
187
- Of course, you can also pass `:text` and `:html` options for the exact text/html bodies of the sent emails.
256
+ Of course, you can also pass `:text` and `:html` options for the exact text/html bodies of the sent emails as they
257
+ will be passed directly to the Mailgun API.
258
+
259
+ No validation is done from this function, so errors from Mailgun will percolate up to you.
188
260
 
189
261
  ### deployer_username
190
262
 
@@ -192,10 +264,28 @@ This is a default capistrano variable that is defined in the gem. It will use th
192
264
  configured as `:git` or use `whoami` if not. This is handy if you want to notify people of which user
193
265
  actually did the deployment.
194
266
 
267
+ ## Built-in Templates
268
+
269
+ `Capistrano::Mailgun` comes with built-in templates for use with `mailgun.notify_of_deploy`. There are both HTML and Text
270
+ templates which include information such as the sha1 and ref that has been deployed as well as logs of the last
271
+ commits. Use of the Capistrano variable `github_url` will enable links back to the repository and direct links
272
+ to the commits in the log.
273
+
274
+ These files live inside the gem in the `lib/templates` directory, so feel free to pull them out, copy into
275
+ your project and customize.
276
+
277
+ By default, `mailgun.notify_of_deploy` sets `mailgun_text_template` to `:default_text` and `mailgun_html_template`
278
+ to `:default_html`, which signals it to use these built-in templates. Overriding those variables with absolute
279
+ paths to your own templates will signal mailgun to use those. Setting either variable to `nil` will prevent
280
+ `mailgun.notify_of_deploy` from using anything for either the text or HTML portion of the email.
281
+
195
282
  ## Limitations
196
283
 
197
284
  * Only supports ERB for templates. This should be changed in a future release.
198
285
  * Currently requires that ERB templates are on the filesystem. Future releases may allow for inline templates.
286
+ * Support for VCSs other than `:git` is lacking. `Capistrano::Mailgun` has been built with git and Github in mind.
287
+ If anyone has interest in adding support for other another version control system, that would be great.
288
+ Using this with a VCS other than Git may yeild unpredictable results.
199
289
 
200
290
  ## Contributing
201
291
 
@@ -204,3 +294,13 @@ actually did the deployment.
204
294
  3. Commit your changes (`git commit -am 'Added some feature'`)
205
295
  4. Push to the branch (`git push origin my-new-feature`)
206
296
  5. Create new Pull Request
297
+
298
+ ## Acknowledgements
299
+
300
+ `Capistrano::Mailgun` is written by Spike Grobstein and is used in production at [Ticket Evolution](http://www.ticketevolution.com)
301
+
302
+ `Capistrano::Mailgun` leverages the awesome email sending API of [Mailgun.org](http://mailgun.org). You should definitely check it out.
303
+
304
+ ## License
305
+
306
+ `Capistrano::Mailgun` is &copy;2012 Spike Grobstein and licensed under the MIT License. See `LICENSE` file.
@@ -14,7 +14,9 @@ module Capistrano
14
14
 
15
15
  Capistrano.plugin :mailgun, Capistrano::Mailgun
16
16
 
17
- set(:mailgun_subject) { "[Deployment] #{ application.capitalize } completed" }
17
+ set(:mailgun_subject) do
18
+ [ "[Deployment]", fetch(:stage, '').to_s.capitalize, fetch(:application, '').capitalize, 'deploy completed'].join(' ').gsub(/\s+/, ' ')
19
+ end
18
20
 
19
21
  set(:mailgun_api_key) { abort "Please set mailgun_api_key accordingly" }
20
22
  set(:mailgun_domain) { abort "Please set mailgun_domain accordingly" }
@@ -22,22 +24,39 @@ module Capistrano
22
24
  set(:mailgun_recipients) { abort "Please specify mailgun_recipients" }
23
25
  set(:mailgun_recipient_domain) { abort "Please set mailgun_recipient_domain accordingly" }
24
26
 
27
+ # set these to nil to not use, or set to path to your custom template
28
+ set :mailgun_text_template, :deploy_text
29
+ set :mailgun_html_template, :deploy_html
30
+
25
31
  set(:deployer_username) do
26
- if fetch(:scm, nil).to_sym == :git
32
+ if fetch(:scm, '').to_sym == :git
27
33
  `git config user.name`.chomp
28
34
  else
29
35
  `whoami`.chomp
30
36
  end
31
37
  end
32
38
 
39
+ # default mailgun email tasks
40
+ desc <<-DESC
41
+ Send a mailgun deployment notification.
42
+
43
+ This is here for convenience so you can force a notification to
44
+ be sent from the commandline and also to simplify configuring
45
+ after-deploy hooks and even after-mailgun-notify hooks.
46
+ DESC
47
+ task :mailgun_notify do
48
+ mailgun.notify_of_deploy
49
+ end
50
+
51
+
33
52
 
34
53
  end # config.load
35
54
  end
36
55
 
37
56
  # Simple wrapper for sending an email with a given template
38
57
  # Supports all options that the Mailgun API supports. In addition, it also accepts:
39
- # +:text_template+ -- the path to the template for the text body. It will be processed and interpolated and set the +text+ field when doing the API call.
40
- # +:html_template+ -- the path to the template for the html body. It will be processed and interpolated and set the +html+ field when doing the API call.
58
+ # * +:text_template+ -- the path to the template for the text body. It will be processed and interpolated and set the +text+ field when doing the API call.
59
+ # * +:html_template+ -- the path to the template for the html body. It will be processed and interpolated and set the +html+ field when doing the API call.
41
60
  def send_email(options)
42
61
  options = process_send_email_options(options)
43
62
 
@@ -46,38 +65,35 @@ module Capistrano
46
65
 
47
66
  # Sends the email via the Mailgun API using variables configured in Capistrano.
48
67
  # It depends on the following Capistrano vars in addition to the default:
49
- # +mailgun_recipients+
50
- # +mailgun_from+
51
- # +mailgun_subject+
68
+ # * +mailgun_recipients+
69
+ # * +mailgun_from+
70
+ # * +mailgun_subject+
52
71
  # Requires one or both of the following:
53
- # +mailgun_text_template+
54
- # +mailgun_html_template+
72
+ # * +mailgun_text_template+
73
+ # * +mailgun_html_template+
55
74
  #
56
75
  # See README for explanations of the above variables.
57
76
  def notify_of_deploy
58
77
  options = {
59
- :to => build_recipients( fetch(:mailgun_recipients) ),
78
+ :to => fetch(:mailgun_recipients),
60
79
  :from => fetch(:mailgun_from),
61
80
  :subject => fetch(:mailgun_subject)
62
81
  }
63
82
 
83
+ options[:cc] = fetch(:mailgun_cc) if fetch(:mailgun_cc, nil)
84
+ options[:bcc] = fetch(:mailgun_bcc) if fetch(:mailgun_bcc, nil)
85
+
64
86
  if fetch(:mailgun_text_template, nil).nil? && fetch(:mailgun_html_template, nil).nil?
65
87
  abort "You must specify one (or both) of mailgun_text_template and mailgun_html_template to use notify_of_deploy"
66
88
  end
67
89
 
68
- options[:text_template] = fetch(:mailgun_text_template) if fetch(:mailgun_text_template, nil)
69
- options[:html_template] = fetch(:mailgun_html_template) if fetch(:mailgun_html_template, nil)
90
+ options[:text_template] = fetch(:mailgun_text_template, nil)
91
+ options[:html_template] = fetch(:mailgun_html_template, nil)
70
92
 
71
93
  send_email options
72
94
  end
73
95
 
74
- # Placeholder method for hunting down templates. Currently does nothing.
75
- def find_template(t)
76
- return t
77
- File.join( File.dirname(__FILE__), t )
78
- end
79
-
80
- # Given an array of +recipients+, it returns a comma-delimited, deduplicated string, suitable for populating the +to+ field of a Mailgun API call.
96
+ # Given an array of +recipients+, it returns a comma-delimited, deduplicated string, suitable for populating the +to+, +cc+, and +bcc+ fields of a Mailgun API call.
81
97
  # Optionally, it will take a +default_domain+ which will automatically be appended to any unqualified recipients (eg: 'spike' => 'spike@example.com')
82
98
  def build_recipients(recipients, default_domain=nil)
83
99
  [*recipients].map do |r|
@@ -86,19 +102,64 @@ module Capistrano
86
102
  else
87
103
  "#{ r }@#{ default_domain || fetch(:mailgun_recipient_domain) }"
88
104
  end
89
- end.uniq
105
+ end.uniq.sort.join(',')
106
+ end
107
+
108
+ # git log between +first_ref+ to +last_ref+
109
+ def log_output(first_ref, last_ref)
110
+ return @log_output unless @log_output.nil?
111
+
112
+ log_output = run_locally("git log --oneline #{ first_ref }..#{ last_ref }")
113
+
114
+ @log_output = log_output = log_output.split("\n").map do |line|
115
+ fields = line.split("\s", 2)
116
+ [ fields[0], fields[1] ]
117
+ end
90
118
  end
91
119
 
92
120
  private
93
121
 
122
+ def default_deploy_text_template_path
123
+ default_template_path 'default.txt.erb'
124
+ end
125
+
126
+ def default_deploy_html_template_path
127
+ default_template_path 'default.html.erb'
128
+ end
129
+
130
+ def default_template_path(name)
131
+ File.join( File.dirname(__FILE__), 'templates', name)
132
+ end
133
+
134
+ def find_template(t)
135
+ case t
136
+ when :deploy_text then default_deploy_text_template_path
137
+ when :deploy_html then default_deploy_html_template_path
138
+ else
139
+ abort "Unknown template symbol: #{ t }" if t.is_a?(Symbol)
140
+ abort "Template not found: #{ t }" unless File.exists?(t)
141
+ t
142
+ end
143
+ end
144
+
94
145
  # apply templates and all that jazz
95
146
  def process_send_email_options(options)
96
147
  text_template = options.delete(:text_template)
97
148
  html_template = options.delete(:html_template)
98
149
 
150
+ options[:to] = build_recipients(options[:to]) unless options[:to].nil?
151
+ options[:cc] = build_recipients(options[:cc]) unless options[:cc].nil?
152
+ options[:bcc] = build_recipients(options[:bcc]) unless options[:bcc].nil?
153
+
99
154
  options[:text] = ERB.new( File.open( find_template(text_template) ).read ).result(self.binding) if text_template
100
155
  options[:html] = ERB.new( File.open( find_template(html_template) ).read ).result(self.binding) if html_template
101
156
 
157
+ # clean up the text template a little
158
+ if options[:text]
159
+ options[:text].gsub! /^ +/, ''
160
+ options[:text].gsub! /\n{3,}/, "\n\n"
161
+ end
162
+
102
163
  options
103
164
  end
104
165
 
@@ -1,5 +1,5 @@
1
1
  module Capistrano
2
2
  module Mailgun
3
- VERSION = "1.0.2"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
@@ -0,0 +1,149 @@
1
+ <html>
2
+ <head>
3
+ <style>
4
+ body {
5
+ font: 12px "Helvetica", "Lucida Grande", "Trebuchet MS", Verdana, sans-serif;
6
+ }
7
+ .section h2 {
8
+ color: #999;
9
+ margin: 0;
10
+ }
11
+
12
+ .section {
13
+ margin-bottom: 10px;
14
+ border-radius: 10px;
15
+ background-color: #eee;
16
+
17
+ padding: 5px 20px;
18
+ }
19
+
20
+ dt {
21
+ width: 15%;
22
+ margin-right: 10px;
23
+ display: inline-block;
24
+ white-space: nowrap;
25
+
26
+ clear: both;
27
+ }
28
+
29
+ dd {
30
+ width: 65%;
31
+ display: inline-block;
32
+ }
33
+
34
+ dl dt {
35
+ font-weight: bold;
36
+ }
37
+
38
+ .log ul {
39
+ font-family: monospace;
40
+
41
+ list-style: none;
42
+ }
43
+
44
+ .log ul li {
45
+ margin: 5px;
46
+ }
47
+
48
+ .log ul li a {
49
+ font-weight: bold;
50
+ padding: 2px 5px;
51
+ background-color: #eee;
52
+ color: #666;
53
+ text-decoration: none;
54
+ }
55
+
56
+ .log ul li a:hover {
57
+ text-decoration: underline;
58
+ color: black;
59
+ }
60
+
61
+ </style>
62
+ </head>
63
+ <body>
64
+
65
+ <h1>
66
+ <%= fetch(:stage, '').to_s.capitalize %> <%= application.capitalize %> deployment completed!
67
+ </h1>
68
+
69
+ <div class="section">
70
+ <h2>Deployment Overview</h2>
71
+
72
+ <dl>
73
+ <dt>Deployed by:</dt>
74
+ <dd><%= deployer_username %></dd>
75
+
76
+ <dt>Deployed at:</dt>
77
+ <dd><%= Time.now %></dd>
78
+ </dl>
79
+
80
+ <dl>
81
+ <dt>Application:</dt>
82
+ <dd><%= fetch(:application, 'N/A') %></dd>
83
+
84
+ <dt>Repository:</dt>
85
+ <dd><%= fetch(:repository, 'N/A') %></dd>
86
+
87
+ <% if fetch(:stage, nil) %>
88
+ <dt>Environment:</dt>
89
+ <dd><%= stage %></dd>
90
+ <% end %>
91
+ </div>
92
+
93
+ <div class="section">
94
+ <h2>Deployment Details</h2>
95
+
96
+ <dl>
97
+ <% if fetch(:branch, nil) %>
98
+ <dt>Ref:</dt>
99
+ <dd><%= branch %></dd>
100
+ <% end %>
101
+
102
+ <dt>Sha1:</dt>
103
+ <dd><%= fetch(:latest_revision, 'N/A') %></dd>
104
+
105
+ <dt>Release:</dt>
106
+ <dd><%= fetch(:release_name, 'N/A') %></dd>
107
+
108
+ </dl>
109
+
110
+ <% if fetch(:github_url, nil) %>
111
+ <dl>
112
+ <dt>WWW:</dt>
113
+ <dd><%= github_url %>/tree/<%= latest_revision %></dd>
114
+ </dl>
115
+ <% end %>
116
+ </div>
117
+
118
+ <% if fetch(:mailgun_message, nil) %>
119
+ <div id="mailgun_message" class="section">
120
+ <h2>Custom Message:</h2>
121
+ <p>
122
+ <%= fetch(:mailgun_message) %>
123
+ </p>
124
+ </div>
125
+ <% end %>
126
+
127
+ <% log_output = mailgun.log_output(latest_revision, real_revision) %>
128
+ <% unless log_output.count == 0 %>
129
+ <div class="log">
130
+ <h2>Log:</h2>
131
+
132
+ <ul>
133
+ <% mailgun.log_output(latest_revision, real_revision).each do |line| %>
134
+ <li>
135
+ <% if fetch(:github_url, nil) %>
136
+ <a href="<%= github_url %>/commit/<%= line[0] %>"><%= line[0] %></a>
137
+ <% else %>
138
+ <%= line[0] %>
139
+ <% end %>
140
+
141
+ <%= line[1] %>
142
+ </li>
143
+ <% end %>
144
+ </ul>
145
+ </div>
146
+ <% end %>
147
+
148
+ </body>
149
+ </html>
@@ -0,0 +1,26 @@
1
+ <%= fetch(:stage, '').to_s.capitalize %> <%= application.capitalize %> deployment completed!
2
+
3
+ Deployed by: <%= deployer_username %>
4
+ Deployed at: <%= Time.now %>
5
+
6
+ Application: <%= fetch(:application, 'N/A') %>
7
+ Repository: <%= fetch(:repository, 'N/A') %>
8
+ <% if fetch(:stage, nil) %>Environment: <%= stage %><% end %>
9
+
10
+ <% if fetch(:branch, nil) %>Ref: <%= branch %><% end %>
11
+ Sha1: <%= fetch(:latest_revision, 'N/A') %>
12
+ Release: <%= fetch(:release_name, 'N/A') %>
13
+ <% if fetch(:mailgun_message, nil) %>
14
+ Custom Message:
15
+ <%= fetch(:mailgun_message) %>
16
+ <% end %>
17
+
18
+ <% if fetch(:url, nil) %>WWW: <%= fetch(:url) %><% end %>
19
+ <% log_output = mailgun.log_output(latest_revision, real_revision) %>
20
+ <% unless log_output.count == 0 %>
21
+ Log:
22
+ ---------------------------------------------------------------------------------
23
+ <% log_output.each do |line| %>
24
+ <%= line.join(' ') %>
25
+ <% end %>
26
+ <% end %>
@@ -8,9 +8,11 @@ describe Capistrano::Mailgun do
8
8
 
9
9
  before do
10
10
  Capistrano::Mailgun.load_into(config)
11
+
12
+ RestClient.stub(:post)
11
13
  end
12
14
 
13
- let!(:mailgun) { config.mailgun }
15
+ let(:mailgun) { config.mailgun }
14
16
 
15
17
  context '#buid_recipients' do
16
18
  let(:email_1) { 'spike@example.com' }
@@ -21,15 +23,15 @@ describe Capistrano::Mailgun do
21
23
  end
22
24
 
23
25
  it "should accept a single recipient (not an array)" do
24
- build_recipients(email_1).should == [email_1]
26
+ build_recipients(email_1).should == email_1
25
27
  end
26
28
 
27
29
  it "should accept an array of recipeints" do
28
- build_recipients( [email_1, email_2] ).should == [email_1, email_2]
30
+ build_recipients( [email_1, email_2] ).should == [email_1, email_2].sort.join(',')
29
31
  end
30
32
 
31
33
  it "should deduplicate emails in the recipients" do
32
- build_recipients( [email_1, email_2, email_1] ).should == [email_1, email_2]
34
+ build_recipients( [email_1, email_2, email_1] ).should == [email_1, email_2].sort.join(',')
33
35
  end
34
36
 
35
37
  context "when working with unqualified email addresses" do
@@ -40,11 +42,11 @@ describe Capistrano::Mailgun do
40
42
  end
41
43
 
42
44
  it "should add the mailgun_recipient_domain to any unqualified email addresses" do
43
- build_recipients( %w( spike ) ).should == ['spike@another.com']
45
+ build_recipients( %w( spike ) ).should == 'spike@another.com'
44
46
  end
45
47
 
46
48
  it "should accept a mix of qualified and unqualified email addresses" do
47
- build_recipients( [email_1, 'spike']).should == [email_1, 'spike@another.com']
49
+ build_recipients( [email_1, 'spike']).should == [email_1, 'spike@another.com'].sort.join(',')
48
50
  end
49
51
 
50
52
  end
@@ -57,7 +59,7 @@ describe Capistrano::Mailgun do
57
59
 
58
60
  it "should use the passed default_domain over the mailgun_recipient_domain if it's passed" do
59
61
  config.load { set :mailgun_recipient_domain, 'example.com' }
60
- build_recipients( ['spike'], 'awesome.com' ).should == ['spike@awesome.com']
62
+ build_recipients( ['spike'], 'awesome.com' ).should == 'spike@awesome.com'
61
63
  end
62
64
  end
63
65
 
@@ -66,9 +68,46 @@ describe Capistrano::Mailgun do
66
68
 
67
69
  context "#find_template" do
68
70
 
69
- # future behavior might be different
70
- it "should return the path passed to it" do
71
- mailgun.find_template('asdf').should == 'asdf'
71
+ def find_template(t)
72
+ mailgun.send(:find_template, t)
73
+ end
74
+
75
+ context "when dealing with a path" do
76
+
77
+ it "should return the path if the file exists" do
78
+ File.stub!(:exists? => true)
79
+
80
+ find_template('asdf').should == 'asdf'
81
+ end
82
+
83
+ it "should not raise an error if the file exists" do
84
+ File.stub!(:exists? => true)
85
+
86
+ lambda { find_template('adsf') }.should_not raise_error
87
+ end
88
+
89
+ it "should raise an error if the path doesn't exist" do
90
+ File.stub!(:exists? => false)
91
+
92
+ lambda { find_template('asdf') }.should raise_error
93
+ end
94
+
95
+ end
96
+
97
+ context "when dealing with a symbol" do
98
+
99
+ it "should return the default_deploy_text_template_path for :deploy_text" do
100
+ mailgun.should_receive(:default_deploy_text_template_path)
101
+
102
+ find_template(:deploy_text)
103
+ end
104
+
105
+ it "should return the default_deploy_html_template_path for :deploy_html" do
106
+ mailgun.should_receive(:default_deploy_html_template_path)
107
+
108
+ find_template(:deploy_html)
109
+ end
110
+
72
111
  end
73
112
 
74
113
  end
@@ -132,6 +171,65 @@ describe Capistrano::Mailgun do
132
171
  lambda { mailgun.notify_of_deploy }.should_not raise_error
133
172
  end
134
173
 
174
+ context "when using cc and bcc" do
175
+ let(:cc_email) { 'cc_email@example.com' }
176
+ let(:bcc_email) { 'bcc_email@example.com' }
177
+
178
+ context "when cc and bcc are included" do
179
+ before do
180
+
181
+ ERB.stub!(:new => mock(:result => 'completed template'))
182
+
183
+ config.load do
184
+ set :application, 'some application'
185
+
186
+ set :mailgun_api_key, 'asdfasdf'
187
+ set :mailgun_domain, 'example.com'
188
+
189
+ set :mailgun_cc, 'cc_email@example.com'
190
+ set :mailgun_bcc, 'bcc_email@example.com'
191
+
192
+ set :mailgun_recipient_domain, 'example.com'
193
+ end
194
+ end
195
+
196
+ after do
197
+ mailgun.notify_of_deploy
198
+ end
199
+
200
+ it "should recieve process_send_email_options with cc and bcc values" do
201
+ mailgun.should_receive(:process_send_email_options) do |options|
202
+ options[:cc].should_not be_nil
203
+ options[:bcc].should_not be_nil
204
+ end
205
+ end
206
+
207
+ it "should run build_recipients on cc and bcc" do
208
+ mailgun.should_receive(:build_recipients).with('people@example.com')
209
+ mailgun.should_receive(:build_recipients).with(cc_email)
210
+ mailgun.should_receive(:build_recipients).with(bcc_email)
211
+ end
212
+
213
+ it "should set the options in send_email to include cc if it's there" do
214
+ config.load do
215
+ set :mailgun_cc, nil
216
+ end
217
+
218
+ mailgun.should_not_receive(:build_recipients).with(cc_email)
219
+ end
220
+
221
+ it "should set the options in send_email to include bcc if it's there" do
222
+ config.load do
223
+ set :mailgun_cc, nil
224
+ end
225
+
226
+ mailgun.should_not_receive(:build_recipients).with(cc_email)
227
+ end
228
+
229
+ end
230
+
231
+ end
232
+
135
233
  end
136
234
 
137
235
  context "#process_send_email_options" do
@@ -0,0 +1,165 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Integration testing for Capistrano::Mailgun" do
4
+
5
+ let(:config) do
6
+ Capistrano::Configuration.new
7
+ end
8
+
9
+ before do
10
+ Capistrano::Mailgun.load_into(config)
11
+
12
+ RestClient.stub(:post)
13
+ end
14
+
15
+ let(:mailgun) { config.mailgun }
16
+
17
+ context "when overriding defaults" do
18
+
19
+ before do
20
+ config.stub!(:run_locally => 'local output')
21
+
22
+ config.load do
23
+ set :application, 'testing'
24
+ set :scm, :git
25
+
26
+ # deploy stuff stubbing
27
+ set :latest_revision, 'asdfasdf'
28
+ set :real_revision, 'asdfasdf'
29
+
30
+ # base Capistrano::Mailgun config
31
+ set :mailgun_api_key, 'api-dummy-key'
32
+ set :mailgun_domain, 'example.com'
33
+ end
34
+ end
35
+
36
+ context "when using mailgun.notify_of_deploy" do
37
+ before do
38
+ config.load do
39
+ set :mailgun_from, 'noreply@example.com'
40
+ set :mailgun_recipients, 'everyone@example.com'
41
+ end
42
+ end
43
+
44
+ after do
45
+ mailgun.notify_of_deploy
46
+ end
47
+
48
+
49
+ it "should allow user to unset text template" do
50
+ config.load do
51
+ set :mailgun_text_template, nil
52
+ end
53
+
54
+ RestClient.should_receive(:post) do |url, opts|
55
+ opts.has_key?(:text).should be_false
56
+ opts.has_key?(:html).should be_true
57
+ end
58
+ end
59
+
60
+ it "should allow user to unset html template" do
61
+ config.load do
62
+ set :mailgun_html_template, nil
63
+ end
64
+
65
+ RestClient.should_receive(:post) do |url, opts|
66
+ opts.has_key?(:text).should be_true
67
+ opts.has_key?(:html).should be_false
68
+ end
69
+ end
70
+
71
+ context "email subject" do
72
+
73
+ it "should include the stage if that's defined" do
74
+ config.load do
75
+ set :stage, 'production'
76
+ end
77
+
78
+ RestClient.should_receive(:post) do |url, opts|
79
+ opts[:subject].should match(/\bproduction\b/i)
80
+ end
81
+ end
82
+
83
+ it "should allow overriding of subject" do
84
+ config.load do
85
+ set :mailgun_subject, 'Test subject'
86
+ end
87
+
88
+ RestClient.should_receive(:post) do |url, opts|
89
+ opts[:subject].should == 'Test subject'
90
+ end
91
+ end
92
+ end
93
+
94
+ it "should use mailgun_from for :from field" do
95
+ RestClient.should_receive(:post) do |url, opts|
96
+ opts[:from].should == 'noreply@example.com'
97
+ end
98
+ end
99
+
100
+ it "should use mailgun_recipients for :to field" do
101
+ RestClient.should_receive(:post) do |url, opts|
102
+ opts[:to].should == 'everyone@example.com'
103
+ end
104
+ end
105
+
106
+ context "when using mailgun_cc" do
107
+ it "should use CC field if it's set" do
108
+ config.load do
109
+ set :mailgun_cc, 'cc@example.com'
110
+ end
111
+
112
+ RestClient.should_receive(:post) do |url, opts|
113
+ opts[:cc].should == 'cc@example.com'
114
+ end
115
+ end
116
+
117
+ it "should not use CC field if it's not set" do
118
+ RestClient.should_receive(:post) do |url, opts|
119
+ opts.has_key?(:cc).should be_false
120
+ end
121
+ end
122
+ end
123
+
124
+ context "when using mailgun_bcc" do
125
+ it "should use bcc field if it's set" do
126
+ config.load do
127
+ set :mailgun_bcc, 'bcc@example.com'
128
+ end
129
+
130
+ RestClient.should_receive(:post) do |url, opts|
131
+ opts[:bcc].should == 'bcc@example.com'
132
+ end
133
+ end
134
+
135
+ it "should not use bcc field if it's not set" do
136
+ RestClient.should_receive(:post) do |url, opts|
137
+ opts.has_key?(:bcc).should be_false
138
+ end
139
+ end
140
+ end
141
+
142
+ context "when using mailgun_message" do
143
+ it "should include a mailgun_message if set" do
144
+ config.load do
145
+ set :mailgun_message, '_custom_message_'
146
+ end
147
+
148
+ RestClient.should_receive(:post) do |url, opts|
149
+ opts[:text].should include('_custom_message_')
150
+ opts[:html].should include('_custom_message_')
151
+ end
152
+ end
153
+
154
+ it "should not have the custom_message div if no custom_message is set" do
155
+ RestClient.should_receive(:post) do |url, opts|
156
+ opts[:html].should_not include('id="mailgun_message"')
157
+ end
158
+ end
159
+ end
160
+
161
+ end
162
+
163
+ end
164
+
165
+ end
@@ -8,10 +8,6 @@ $: << File.dirname(__FILE__) + '/../lib'
8
8
  require 'capistrano'
9
9
  require 'capistrano-mailgun'
10
10
 
11
- Rspec.configure do |config|
12
- # config
13
- end
14
-
15
11
  def fixture_path(filename)
16
12
  File.join( File.dirname(__FILE__), 'fixtures', filename )
17
13
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano-mailgun
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-15 00:00:00.000000000 Z
12
+ date: 2012-10-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano
@@ -54,6 +54,7 @@ files:
54
54
  - .gitignore
55
55
  - .rspec
56
56
  - .travis.yml
57
+ - CHANGELOG.md
57
58
  - Gemfile
58
59
  - LICENSE
59
60
  - README.md
@@ -61,9 +62,12 @@ files:
61
62
  - capistrano-mailgun.gemspec
62
63
  - lib/capistrano-mailgun.rb
63
64
  - lib/capistrano-mailgun/version.rb
65
+ - lib/templates/default.html.erb
66
+ - lib/templates/default.txt.erb
64
67
  - spec/capistrano-mailgun_spec.rb
65
68
  - spec/fixtures/html_body.erb
66
69
  - spec/fixtures/text_body.erb
70
+ - spec/integration_spec.rb
67
71
  - spec/spec_helper.rb
68
72
  homepage: ''
69
73
  licenses: []
@@ -79,7 +83,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
79
83
  version: '0'
80
84
  segments:
81
85
  - 0
82
- hash: -2168870135844714304
86
+ hash: 4576376367349129326
83
87
  required_rubygems_version: !ruby/object:Gem::Requirement
84
88
  none: false
85
89
  requirements:
@@ -88,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
92
  version: '0'
89
93
  segments:
90
94
  - 0
91
- hash: -2168870135844714304
95
+ hash: 4576376367349129326
92
96
  requirements: []
93
97
  rubyforge_project:
94
98
  rubygems_version: 1.8.24
@@ -99,4 +103,5 @@ test_files:
99
103
  - spec/capistrano-mailgun_spec.rb
100
104
  - spec/fixtures/html_body.erb
101
105
  - spec/fixtures/text_body.erb
106
+ - spec/integration_spec.rb
102
107
  - spec/spec_helper.rb