capistrano-payload 0.1.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +3 -0
- data/Gemfile +3 -0
- data/README.md +19 -4
- data/Rakefile +11 -0
- data/capistrano-payload.gemspec +7 -4
- data/lib/capistrano-payload/capistrano_integration.rb +18 -4
- data/lib/capistrano-payload/format.rb +66 -0
- data/lib/capistrano-payload/payload.rb +37 -17
- data/lib/capistrano-payload/request.rb +35 -0
- data/lib/capistrano-payload/version.rb +1 -1
- data/lib/capistrano-payload.rb +3 -0
- data/spec/fixtures/payload.form +1 -0
- data/spec/fixtures/payload.json +19 -0
- data/spec/fixtures/payload.xml +20 -0
- data/spec/fixtures/payload.yml +15 -0
- data/spec/format_spec.rb +34 -0
- data/spec/payload_spec.rb +42 -0
- data/spec/request_spec.rb +24 -0
- data/spec/spec_helper.rb +52 -0
- data/spec/spec_utils.rb +17 -0
- metadata +65 -10
data/.rspec
ADDED
data/Gemfile
ADDED
data/README.md
CHANGED
@@ -20,25 +20,40 @@ Then configure URL:
|
|
20
20
|
To test if it works type:
|
21
21
|
|
22
22
|
cap payload:deploy
|
23
|
+
|
24
|
+
The best way to test out is to use http://www.postbin.org/.
|
25
|
+
|
26
|
+
## Options
|
27
|
+
|
28
|
+
- payload_url — Primary URL where the data would be sent (required)
|
29
|
+
- payload_format — Payload format. Must be one of :json (default), :form, :yaml, :xml
|
30
|
+
- payload_params — Extra parameters to the request (api_key, etc.). *Note: extra parameters wont be added to the payload.*
|
31
|
+
- payload_message — Ask for deployment comment. (default: true)
|
23
32
|
|
24
33
|
## Payload structure
|
25
34
|
|
26
|
-
Plugin will sent JSON
|
35
|
+
Plugin will sent a payload in one of the formats (FORM, JSON, YAML, XML) data via POST method.
|
27
36
|
|
28
|
-
Here is
|
37
|
+
Here is an example data:
|
29
38
|
|
30
39
|
{
|
31
40
|
"capistrano": {
|
41
|
+
"version": "2.6.0",
|
32
42
|
"application": "APP_NAME",
|
33
|
-
"deployer":
|
43
|
+
"deployer": {
|
44
|
+
"user": "sosedoff",
|
45
|
+
"hostname": "localhost",
|
46
|
+
}
|
34
47
|
"timestamp": "2011-07-21 19:09:52 -0500",
|
48
|
+
"message": "Release 1.0.0",
|
35
49
|
"source": {
|
36
50
|
"branch": "master",
|
37
51
|
"revision": "b18ffa822c16c028765800d0c4d22bfd5e4f3bf9",
|
38
52
|
"repository": "git@github.com:repository.git"
|
39
53
|
},
|
40
54
|
"action": "deploy"
|
41
|
-
}
|
55
|
+
},
|
56
|
+
"payload_version": "0.2.0"
|
42
57
|
}
|
43
58
|
|
44
59
|
That's it. Ready to roll.
|
data/Rakefile
ADDED
data/capistrano-payload.gemspec
CHANGED
@@ -15,9 +15,12 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
|
16
16
|
gem.require_paths = ['lib']
|
17
17
|
|
18
|
-
gem.add_development_dependency 'rspec',
|
18
|
+
gem.add_development_dependency 'rspec', '~> 2.6'
|
19
|
+
gem.add_development_dependency 'xml-simple', '~> 1.1'
|
20
|
+
gem.add_development_dependency 'webmock', '~> 1.6'
|
19
21
|
|
20
|
-
gem.add_runtime_dependency 'capistrano',
|
21
|
-
gem.add_runtime_dependency 'rest-client',
|
22
|
-
gem.add_runtime_dependency 'multi_json',
|
22
|
+
gem.add_runtime_dependency 'capistrano', '~> 2.6'
|
23
|
+
gem.add_runtime_dependency 'rest-client', '~> 1.6'
|
24
|
+
gem.add_runtime_dependency 'multi_json', '~> 1.0'
|
25
|
+
gem.add_runtime_dependency 'builder', '~> 3.0'
|
23
26
|
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'capistrano'
|
2
|
+
require 'capistrano/version'
|
3
|
+
require 'socket'
|
2
4
|
|
3
5
|
module CapistranoPayload
|
4
6
|
class CapistranoIntegration
|
@@ -8,12 +10,18 @@ module CapistranoPayload
|
|
8
10
|
abort 'Payload URL required! set :payload_url'
|
9
11
|
}
|
10
12
|
|
11
|
-
_cset(:
|
13
|
+
_cset(:payload_message) { true }
|
14
|
+
_cset(:payload_format) { :json }
|
15
|
+
_cset(:payload_params) { Hash.new }
|
12
16
|
|
13
17
|
_cset(:payload_data) {
|
14
18
|
{
|
19
|
+
:version => Capistrano::Version.to_s.strip,
|
15
20
|
:application => fetch(:application),
|
16
|
-
:deployer =>
|
21
|
+
:deployer => {
|
22
|
+
:user => ENV['USER'] || ENV['USERNAME'] || 'n/a',
|
23
|
+
:hostname => ENV['HOSTNAME'] || Socket.gethostname
|
24
|
+
},
|
17
25
|
:timestamp => Time.now,
|
18
26
|
:source => {
|
19
27
|
:branch => fetch(:branch),
|
@@ -26,19 +34,25 @@ module CapistranoPayload
|
|
26
34
|
namespace :payload do
|
27
35
|
task :deploy, :roles => :app do
|
28
36
|
logger.debug("Sending deployment notification to #{fetch(:payload_url)}")
|
37
|
+
message = payload_message == true ? Capistrano::CLI.ui.ask("Deployment message (none): ", nil) : ''
|
29
38
|
begin
|
30
|
-
CapistranoPayload::Payload.new('deploy', payload_data).deliver(
|
39
|
+
CapistranoPayload::Payload.new('deploy', message, payload_data, payload_format, payload_params).deliver(payload_url)
|
31
40
|
rescue DeliveryError => err
|
32
41
|
logger.debug("Payload delivery error: #{err.message}")
|
42
|
+
rescue ConfigurationError => err
|
43
|
+
logger.debug("Payload configuration error: #{err.message}")
|
33
44
|
end
|
34
45
|
end
|
35
46
|
|
36
47
|
task :rollback, :roles => :app do
|
37
48
|
logger.debug("Sending rollback notification to #{fetch(:payload_url)}")
|
49
|
+
message = payload_message == true ? Capistrano::CLI.ui.ask("Rollback message (none): ", nil) : ''
|
38
50
|
begin
|
39
|
-
CapistranoPayload::Payload.new('rollback', payload_data).deliver(
|
51
|
+
CapistranoPayload::Payload.new('rollback', message, payload_data, payload_format, payload_params).deliver(payload_url)
|
40
52
|
rescue DeliveryError => err
|
41
53
|
logger.debug("Payload delivery error: #{err.message}")
|
54
|
+
rescue ConfigurationError => err
|
55
|
+
logger.debug("Payload configuration error: #{err.message}")
|
42
56
|
end
|
43
57
|
end
|
44
58
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
require 'yaml'
|
3
|
+
require 'builder'
|
4
|
+
require 'time'
|
5
|
+
|
6
|
+
module CapistranoPayload
|
7
|
+
module Format
|
8
|
+
# Allowed formats
|
9
|
+
FORMATS = [:form, :json, :yaml, :xml]
|
10
|
+
|
11
|
+
# Method processing assignment
|
12
|
+
FORMAT_METHODS = {
|
13
|
+
:form => :to_hash,
|
14
|
+
:json => :to_json,
|
15
|
+
:yaml => :to_yaml,
|
16
|
+
:xml => :to_xml
|
17
|
+
}
|
18
|
+
|
19
|
+
# Returns a payload as HASH
|
20
|
+
#
|
21
|
+
def to_hash
|
22
|
+
{
|
23
|
+
:capistrano => @data,
|
24
|
+
:payload_version => CapistranoPayload::VERSION
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns a payload as JSON
|
29
|
+
#
|
30
|
+
def to_json
|
31
|
+
MultiJson.encode(self.to_hash)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns a payload as YAML
|
35
|
+
#
|
36
|
+
def to_yaml
|
37
|
+
YAML.dump(self.to_hash)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Returns a payload as XML
|
41
|
+
#
|
42
|
+
def to_xml
|
43
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
44
|
+
xml.instruct!(:xml, :version => '1.0', :encoding => 'UTF-8')
|
45
|
+
xml.payload do |p|
|
46
|
+
p.capistrano do |c|
|
47
|
+
c.action @data[:action]
|
48
|
+
c.message @data[:message]
|
49
|
+
c.version @data[:version]
|
50
|
+
c.application @data[:application]
|
51
|
+
c.deployer do |d|
|
52
|
+
c.user @data[:deployer][:user]
|
53
|
+
c.hostname @data[:deployer][:hostname]
|
54
|
+
end
|
55
|
+
c.timestamp @data[:timestamp].iso8601
|
56
|
+
c.source do |s|
|
57
|
+
c.branch @data[:source][:branch]
|
58
|
+
c.revision @data[:source][:revision]
|
59
|
+
c.repository @data[:source][:repository]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
p.payload_version CapistranoPayload::VERSION
|
63
|
+
end.to_s
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -1,30 +1,50 @@
|
|
1
|
-
require 'rest-client'
|
2
|
-
require 'multi_json'
|
3
|
-
|
4
1
|
module CapistranoPayload
|
5
|
-
class
|
2
|
+
class ConfigurationError < StandardError ; end
|
3
|
+
class DeliveryError < StandardError ; end
|
6
4
|
|
7
5
|
class Payload
|
6
|
+
include CapistranoPayload::Format
|
7
|
+
include CapistranoPayload::Request
|
8
|
+
|
9
|
+
# Allowed actions
|
10
|
+
ACTIONS = ['deploy', 'rollback']
|
11
|
+
|
8
12
|
attr_reader :action
|
13
|
+
attr_reader :message
|
9
14
|
attr_reader :data
|
15
|
+
attr_reader :format
|
10
16
|
attr_reader :params
|
11
17
|
|
12
18
|
# Initialize a new Payload object
|
13
19
|
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
20
|
+
# action - Deployment action (deploy, rollback)
|
21
|
+
# message - Deployment message (optional)
|
22
|
+
# data - Payload data
|
23
|
+
# format - Payload format (:json, :form). Default: json
|
24
|
+
# params - Extra parameters to payload (api_key, etc.), default: {}
|
25
|
+
# Could not contain 'capistrano' key. Will be removed if present.
|
26
|
+
# Should be a hash
|
18
27
|
#
|
19
|
-
def initialize(action, data, params={})
|
20
|
-
@action
|
21
|
-
@
|
22
|
-
@
|
28
|
+
def initialize(action, message, data, format=:json, params={})
|
29
|
+
@action = action
|
30
|
+
@message = message.strip
|
31
|
+
@data = data.merge(:action => @action, :message => @message)
|
32
|
+
@format = format.to_sym
|
33
|
+
@params = params.kind_of?(Hash) ? params : {}
|
34
|
+
|
35
|
+
unless ACTIONS.include?(@action)
|
36
|
+
raise ConfigurationError, "Invalid payload action: #{action}."
|
37
|
+
end
|
38
|
+
|
39
|
+
# Check if we have an invalid format
|
40
|
+
unless FORMATS.include?(@format)
|
41
|
+
raise ConfigurationError, "Invalid payload format: #{format}."
|
42
|
+
end
|
23
43
|
|
24
|
-
# Check if we have '
|
44
|
+
# Check if we have 'payload' keys (string or symbolic)
|
25
45
|
unless @params.empty?
|
26
|
-
@params.delete(:
|
27
|
-
@params.delete('
|
46
|
+
@params.delete(:payload)
|
47
|
+
@params.delete('payload')
|
28
48
|
end
|
29
49
|
end
|
30
50
|
|
@@ -33,9 +53,9 @@ module CapistranoPayload
|
|
33
53
|
# url - Target url
|
34
54
|
#
|
35
55
|
def deliver(url)
|
36
|
-
payload =
|
56
|
+
payload = self.send(FORMAT_METHODS[@format])
|
37
57
|
begin
|
38
|
-
|
58
|
+
request(:post, url, {:payload => payload}.merge(@params), format)
|
39
59
|
rescue Exception => ex
|
40
60
|
raise DeliveryError, ex.message
|
41
61
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
|
3
|
+
module CapistranoPayload
|
4
|
+
module Request
|
5
|
+
TIMEOUT = 4
|
6
|
+
OPEN_TIMEOUT = 4
|
7
|
+
|
8
|
+
CONTENT_TYPES = {
|
9
|
+
:form => 'application/x-www-form-urlencoded',
|
10
|
+
:json => 'application/json',
|
11
|
+
:yaml => 'application/x-yaml',
|
12
|
+
:xml => 'application/xml'
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
# Performs a HTTP request
|
16
|
+
#
|
17
|
+
# method - Request method (:get, :post, :put, :delete)
|
18
|
+
# url - Target URL
|
19
|
+
# payload - Delivery content
|
20
|
+
# format - Delivery format
|
21
|
+
#
|
22
|
+
def request(method, url, payload, format)
|
23
|
+
opts = {
|
24
|
+
:method => method,
|
25
|
+
:url => url,
|
26
|
+
:payload => payload,
|
27
|
+
:headers => {:content_type => CONTENT_TYPES[format]},
|
28
|
+
:timeout => TIMEOUT,
|
29
|
+
:open_timeout => OPEN_TIMEOUT
|
30
|
+
}
|
31
|
+
|
32
|
+
RestClient::Request.execute(opts)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/capistrano-payload.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
payload[capistrano][version]=2.6.0&payload[capistrano][application]=foobar&payload[capistrano][deployer][user]=username&payload[capistrano][deployer][hostname]=localhost&payload[capistrano][timestamp]=2011-01-01%2000%3A00%3A00%20-0600&payload[capistrano][source][branch]=master&payload[capistrano][source][revision]=abcdef&payload[capistrano][source][repository]=git%40github.com%3Ausername%2Frepo.git&payload[capistrano][action]=deploy&payload[capistrano][message]=Comment&payload[payload_version]=0.3.0
|
@@ -0,0 +1,19 @@
|
|
1
|
+
{
|
2
|
+
"capistrano": {
|
3
|
+
"version": "2.6.0",
|
4
|
+
"application": "foobar",
|
5
|
+
"deployer": {
|
6
|
+
"user": "username",
|
7
|
+
"hostname": "localhost"
|
8
|
+
},
|
9
|
+
"timestamp": "2011-01-01 00:00:00 -0600",
|
10
|
+
"source": {
|
11
|
+
"branch": "master",
|
12
|
+
"revision": "abcdef",
|
13
|
+
"repository": "git@github.com:username/repo.git"
|
14
|
+
},
|
15
|
+
"action": "deploy",
|
16
|
+
"message": "Comment"
|
17
|
+
},
|
18
|
+
"payload_version": "0.3.0"
|
19
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<payload>
|
3
|
+
<capistrano>
|
4
|
+
<action>deploy</action>
|
5
|
+
<message>Comment</message>
|
6
|
+
<version>2.6.0</version>
|
7
|
+
<application>foobar</application>
|
8
|
+
<deployer>
|
9
|
+
<user>username</user>
|
10
|
+
<hostname>localhost</hostname>
|
11
|
+
</deployer>
|
12
|
+
<timestamp>2011-01-01T00:00:00-06:00</timestamp>
|
13
|
+
<source>
|
14
|
+
<branch>master</branch>
|
15
|
+
<revision>abcdef</revision>
|
16
|
+
<repository>git@github.com:username/repo.git</repository>
|
17
|
+
</source>
|
18
|
+
</capistrano>
|
19
|
+
<payload_version>0.3.0</payload_version>
|
20
|
+
</payload>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
:capistrano:
|
3
|
+
:version: 2.6.0
|
4
|
+
:application: foobar
|
5
|
+
:deployer:
|
6
|
+
:user: username
|
7
|
+
:hostname: localhost
|
8
|
+
:timestamp: 2011-01-01 00:00:00 -06:00
|
9
|
+
:source:
|
10
|
+
:branch: master
|
11
|
+
:revision: abcdef
|
12
|
+
:repository: git@github.com:username/repo.git
|
13
|
+
:action: deploy
|
14
|
+
:message: Comment
|
15
|
+
:payload_version: 0.3.0
|
data/spec/format_spec.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'CapistranoPayload::Format' do
|
4
|
+
include CapistranoPayload
|
5
|
+
|
6
|
+
before :all do
|
7
|
+
@payload = Payload.new('deploy', 'Comment', PAYLOAD)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'renders HASH' do
|
11
|
+
data = @payload.to_hash
|
12
|
+
data.key?(:capistrano).should == true
|
13
|
+
data.key?(:payload_version).should == true
|
14
|
+
data[:payload_version].should == CapistranoPayload::VERSION
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'renders JSON' do
|
18
|
+
@payload.to_json == json_fixture('payload.json')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'renders YAML' do
|
22
|
+
@payload.to_yaml.should == fixture('payload.yml')
|
23
|
+
@payload.to_hash.should == yaml_fixture('payload.yml')
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'renders XML' do
|
27
|
+
f = xml_fixture_from_string(@payload.to_xml)
|
28
|
+
|
29
|
+
|
30
|
+
f.keys.should == xml_fixture('payload.xml').keys
|
31
|
+
f.keys.should == @payload.to_hash.keys
|
32
|
+
f[:capistrano].keys.should == xml_fixture('payload.xml')[:capistrano].keys
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'CapistranoPayload::Payload' do
|
4
|
+
include CapistranoPayload
|
5
|
+
|
6
|
+
it 'raises ConfigurationError on invalid action' do
|
7
|
+
proc { Payload.new('foo', '', {}) }.
|
8
|
+
should raise_error ConfigurationError, "Invalid payload action: foo."
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'raises ConfigurationError on invalid format' do
|
12
|
+
proc { Payload.new('deploy', '', {}, :foo) }.
|
13
|
+
should raise_error ConfigurationError, "Invalid payload format: foo."
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'assigns data fields' do
|
17
|
+
p = Payload.new('deploy', 'Comment', PAYLOAD)
|
18
|
+
p.action.should == 'deploy'
|
19
|
+
p.message.should == 'Comment'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'discards an invalid extra parameters container' do
|
23
|
+
p = Payload.new('deploy', 'Comment', PAYLOAD, :json, 'Invalid params')
|
24
|
+
p.params.should be_a Hash
|
25
|
+
p.params.empty?.should == true
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'deletes an invalid extra parameters' do
|
29
|
+
p = Payload.new('deploy', 'Comment', PAYLOAD, :json, {'payload' => 'test', :payload => 'test', :api_key => 'test'})
|
30
|
+
p.params.size.should == 1
|
31
|
+
p.params.key?(:payload).should == false
|
32
|
+
p.params.key?('payload').should == false
|
33
|
+
p.params[:api_key].should == 'test'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'responds to format renderers' do
|
37
|
+
p = Payload.new('deploy', 'Comment', PAYLOAD)
|
38
|
+
Format::FORMAT_METHODS.each_pair do |f, method|
|
39
|
+
p.respond_to?(method).should == true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'CapistranoPayload::Request' do
|
4
|
+
include CapistranoPayload
|
5
|
+
|
6
|
+
it 'raises DeliveryError on failed request' do
|
7
|
+
stub_request(:post, "http://localhost:4567/fail").
|
8
|
+
with(:body => fixture('payload.form'), :headers => {'Content-Type'=>'application/x-www-form-urlencoded'}).
|
9
|
+
to_return(:status => 404, :headers => {})
|
10
|
+
|
11
|
+
p = Payload.new('deploy', 'Comment', PAYLOAD, :form)
|
12
|
+
proc { p.deliver('http://localhost:4567/fail') }.
|
13
|
+
should raise_error DeliveryError, "404 Resource Not Found"
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'delivers a payload' do
|
17
|
+
stub_request(:post, "http://foo.bar.com/payload").
|
18
|
+
with(:body => fixture('payload.form'), :headers => {'Content-Type'=>'application/x-www-form-urlencoded'}).
|
19
|
+
to_return(:status => 200, :headers => {})
|
20
|
+
|
21
|
+
p = Payload.new('deploy', 'Comment', PAYLOAD, :form)
|
22
|
+
p.deliver('http://foo.bar.com/payload')
|
23
|
+
end
|
24
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
$:.unshift File.expand_path("../..", __FILE__)
|
2
|
+
|
3
|
+
require 'spec_utils'
|
4
|
+
require 'xmlsimple'
|
5
|
+
require 'webmock'
|
6
|
+
require 'webmock/rspec'
|
7
|
+
require 'capistrano-payload'
|
8
|
+
|
9
|
+
def fixture_path(file=nil)
|
10
|
+
path = File.expand_path("../fixtures", __FILE__)
|
11
|
+
path = File.join(path, file) unless file.nil?
|
12
|
+
path
|
13
|
+
end
|
14
|
+
|
15
|
+
def fixture(file)
|
16
|
+
File.read(File.join(fixture_path, file))
|
17
|
+
end
|
18
|
+
|
19
|
+
def json_fixture(file)
|
20
|
+
MultiJson.decode(fixture(file))
|
21
|
+
end
|
22
|
+
|
23
|
+
def yaml_fixture(file)
|
24
|
+
YAML.load(fixture(file))
|
25
|
+
end
|
26
|
+
|
27
|
+
def xml_fixture(file)
|
28
|
+
hash = XmlSimple.xml_in(fixture(file), 'ForceArray' => false, 'KeepRoot' => false)
|
29
|
+
hash.recursive_symbolize_keys!
|
30
|
+
hash
|
31
|
+
end
|
32
|
+
|
33
|
+
def xml_fixture_from_string(data)
|
34
|
+
hash = XmlSimple.xml_in(data, 'ForceArray' => false, 'KeepRoot' => false)
|
35
|
+
hash.recursive_symbolize_keys!
|
36
|
+
hash
|
37
|
+
end
|
38
|
+
|
39
|
+
PAYLOAD = {
|
40
|
+
:version => "2.6.0",
|
41
|
+
:application => "foobar",
|
42
|
+
:deployer => {
|
43
|
+
:user => "username",
|
44
|
+
:hostname => "localhost"
|
45
|
+
},
|
46
|
+
:timestamp => Time.mktime(2011, 1, 1, 0, 0, 0),
|
47
|
+
:source => {
|
48
|
+
:branch => 'master',
|
49
|
+
:revision => 'abcdef',
|
50
|
+
:repository => 'git@github.com:username/repo.git'
|
51
|
+
}
|
52
|
+
}
|
data/spec/spec_utils.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
class Hash
|
2
|
+
def symbolize_keys!
|
3
|
+
keys.each do |key|
|
4
|
+
self[(key.to_sym rescue key) || key] = delete(key)
|
5
|
+
end
|
6
|
+
self
|
7
|
+
end
|
8
|
+
|
9
|
+
def recursive_symbolize_keys!
|
10
|
+
symbolize_keys!
|
11
|
+
# symbolize each hash in .values
|
12
|
+
values.each{|h| h.recursive_symbolize_keys! if h.is_a?(Hash) }
|
13
|
+
# symbolize each hash inside an array in .values
|
14
|
+
values.select{|v| v.is_a?(Array) }.flatten.each{|h| h.recursive_symbolize_keys! if h.is_a?(Hash) }
|
15
|
+
self
|
16
|
+
end
|
17
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: capistrano-payload
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.3.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Dan Sosedoff
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-07-
|
13
|
+
date: 2011-07-22 00:00:00 -05:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -25,38 +25,71 @@ dependencies:
|
|
25
25
|
type: :development
|
26
26
|
version_requirements: *id001
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: xml-simple
|
29
29
|
prerelease: false
|
30
30
|
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ~>
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "1.1"
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: webmock
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "1.6"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: capistrano
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
31
53
|
none: false
|
32
54
|
requirements:
|
33
55
|
- - ~>
|
34
56
|
- !ruby/object:Gem::Version
|
35
57
|
version: "2.6"
|
36
58
|
type: :runtime
|
37
|
-
version_requirements: *
|
59
|
+
version_requirements: *id004
|
38
60
|
- !ruby/object:Gem::Dependency
|
39
61
|
name: rest-client
|
40
62
|
prerelease: false
|
41
|
-
requirement: &
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
42
64
|
none: false
|
43
65
|
requirements:
|
44
66
|
- - ~>
|
45
67
|
- !ruby/object:Gem::Version
|
46
68
|
version: "1.6"
|
47
69
|
type: :runtime
|
48
|
-
version_requirements: *
|
70
|
+
version_requirements: *id005
|
49
71
|
- !ruby/object:Gem::Dependency
|
50
72
|
name: multi_json
|
51
73
|
prerelease: false
|
52
|
-
requirement: &
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
53
75
|
none: false
|
54
76
|
requirements:
|
55
77
|
- - ~>
|
56
78
|
- !ruby/object:Gem::Version
|
57
79
|
version: "1.0"
|
58
80
|
type: :runtime
|
59
|
-
version_requirements: *
|
81
|
+
version_requirements: *id006
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: builder
|
84
|
+
prerelease: false
|
85
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "3.0"
|
91
|
+
type: :runtime
|
92
|
+
version_requirements: *id007
|
60
93
|
description: Capistrano plugin that delivers JSON payload to the specified URL
|
61
94
|
email: dan.sosedoff@gmail.com
|
62
95
|
executables: []
|
@@ -67,12 +100,26 @@ extra_rdoc_files: []
|
|
67
100
|
|
68
101
|
files:
|
69
102
|
- .gitignore
|
103
|
+
- .rspec
|
104
|
+
- Gemfile
|
70
105
|
- README.md
|
106
|
+
- Rakefile
|
71
107
|
- capistrano-payload.gemspec
|
72
108
|
- lib/capistrano-payload.rb
|
73
109
|
- lib/capistrano-payload/capistrano_integration.rb
|
110
|
+
- lib/capistrano-payload/format.rb
|
74
111
|
- lib/capistrano-payload/payload.rb
|
112
|
+
- lib/capistrano-payload/request.rb
|
75
113
|
- lib/capistrano-payload/version.rb
|
114
|
+
- spec/fixtures/payload.form
|
115
|
+
- spec/fixtures/payload.json
|
116
|
+
- spec/fixtures/payload.xml
|
117
|
+
- spec/fixtures/payload.yml
|
118
|
+
- spec/format_spec.rb
|
119
|
+
- spec/payload_spec.rb
|
120
|
+
- spec/request_spec.rb
|
121
|
+
- spec/spec_helper.rb
|
122
|
+
- spec/spec_utils.rb
|
76
123
|
has_rdoc: true
|
77
124
|
homepage: https://github.com/sosedoff/capistrano-payload
|
78
125
|
licenses: []
|
@@ -101,5 +148,13 @@ rubygems_version: 1.6.2
|
|
101
148
|
signing_key:
|
102
149
|
specification_version: 3
|
103
150
|
summary: JSON webhook on capistrano deployments
|
104
|
-
test_files:
|
105
|
-
|
151
|
+
test_files:
|
152
|
+
- spec/fixtures/payload.form
|
153
|
+
- spec/fixtures/payload.json
|
154
|
+
- spec/fixtures/payload.xml
|
155
|
+
- spec/fixtures/payload.yml
|
156
|
+
- spec/format_spec.rb
|
157
|
+
- spec/payload_spec.rb
|
158
|
+
- spec/request_spec.rb
|
159
|
+
- spec/spec_helper.rb
|
160
|
+
- spec/spec_utils.rb
|