dereno 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +5 -0
- data/Gemfile +3 -0
- data/README.md +78 -0
- data/Rakefile +9 -0
- data/dereno.gemspec +28 -0
- data/lib/capistrano/release_notes.rb +39 -0
- data/lib/dereno.rb +92 -0
- data/lib/dereno/campfire.rb +40 -0
- data/lib/dereno/git.rb +47 -0
- data/lib/dereno/pivotal.rb +53 -0
- data/lib/dereno/railtie.rb +37 -0
- data/lib/dereno/version.rb +5 -0
- data/test/test_campfire.rb +47 -0
- data/test/test_dereno.rb +43 -0
- data/test/test_git.rb +17 -0
- data/test/test_helper.rb +40 -0
- data/test/test_pivotal.rb +70 -0
- metadata +166 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MDA3YTQ5OThmM2E2ZDY5YTg0MDAwNzEzYWI0MWRlNzU0YmJlZmEzNw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MDgzMzVjODJhMDcxNzVkOGZlZmIxZWEwMWM3YzYxNDc4NThhMTJhZQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZDZhOGNjMmU1ODc5OGY3NjU5MjZjMzc2MWYxMDgyNzFkZWFlNWIwYjY3MzIy
|
10
|
+
OGRjOWNmMDZmMTU3MmE3Y2M0YmMwNzk5MmU5OWViMDgwMzJmYWRjYTYxOWY3
|
11
|
+
NDU3NmM4NjM2MjgyNGYxZDE5MmU1ZWY3MjI2NzFjOGE2YmUxODk=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MWEyOTg0OTdiMzgxYjRhMDI5Y2M1ODRmZDNjMTA1YjExN2JmZGJmNzRjYTNh
|
14
|
+
MjZlMzY5ZGIzZjhjYzZhZmM4NmFhMjE2MjA1MjZhOWI1NWVlZjg4NTA2MzQx
|
15
|
+
YjgzODYyYTk4MzZlZGY2OWIwMmRmZDkzNzgxZDI3NmNiMDFiMGI=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
# DeReNo - Deployments Release Notes
|
2
|
+
|
3
|
+
Show release notes (Git commits / Pivotal Tracker stories) before deployments.
|
4
|
+
|
5
|
+
Notify deployments release notes via email (and optionnal Campfire notification).
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
In your Gemfile :
|
10
|
+
|
11
|
+
```rb
|
12
|
+
gem 'dereno'
|
13
|
+
```
|
14
|
+
|
15
|
+
and then `bundle install`
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
In your deploy.rb or equivalent :
|
20
|
+
|
21
|
+
```rb
|
22
|
+
require 'dereno'
|
23
|
+
|
24
|
+
role :dereno , 'my_host'
|
25
|
+
set :dereno_options, {
|
26
|
+
to: 'team@foo.bar',
|
27
|
+
from: 'deployment@foo.bar',
|
28
|
+
|
29
|
+
# optional Pivotal Tracker credentials
|
30
|
+
pivotal_tracker: {
|
31
|
+
token: 'my_token',
|
32
|
+
project_id: 123456
|
33
|
+
},
|
34
|
+
|
35
|
+
# optional Campfire credentials
|
36
|
+
campfire: {
|
37
|
+
subdomain: 'my_domain',
|
38
|
+
token: 'my_token',
|
39
|
+
room: 'my_room'
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
after 'deploy:restart', 'release_notes:notify'
|
44
|
+
```
|
45
|
+
|
46
|
+
and then after each deployments your team will be notify about what's new in production.
|
47
|
+
|
48
|
+
## Tasks
|
49
|
+
|
50
|
+
Show release notes between local current branch and latest deployed release.
|
51
|
+
```rb
|
52
|
+
bundle exec cap production release_notes:show
|
53
|
+
```
|
54
|
+
|
55
|
+
Deployment release notes (between current and previous deployed releases) notification via email (optionnal Campfire notification).
|
56
|
+
```rb
|
57
|
+
bundle exec cap production release_notes:notify
|
58
|
+
```
|
59
|
+
|
60
|
+
## Email template
|
61
|
+
|
62
|
+
```
|
63
|
+
John deployed MyApp (branch master to production), on 05/08/2012 at 05:29 PM CEST
|
64
|
+
|
65
|
+
*** Pivotal Tracker Stories ***
|
66
|
+
|
67
|
+
[BUG] Users can't upload, https://www.pivotaltracker.com/story/show/12345678
|
68
|
+
|
69
|
+
*** Git Commits ***
|
70
|
+
|
71
|
+
deaf044 [Story #12345678] Fixed upload bug (John)
|
72
|
+
27cf576 [Story #12345678] Fixed upload bug tests (John)
|
73
|
+
```
|
74
|
+
|
75
|
+
## Notes
|
76
|
+
|
77
|
+
This gem also adds a rake task (send_email[path]) to the Rails project.
|
78
|
+
This task is used by the release_notes:notify Capistrano task to send the deployment email *FROM* the server and not from the local machine.
|
data/Rakefile
ADDED
data/dereno.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "dereno/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "dereno"
|
7
|
+
s.version = Dereno::VERSION
|
8
|
+
s.authors = ["Ben Colon", "Axel Vergult"]
|
9
|
+
s.email = ["ben@official.fm", "axel@official.fm"]
|
10
|
+
s.homepage = "http://official.fm"
|
11
|
+
s.summary = %q{Deployments release notes for Rails project using Git}
|
12
|
+
s.description = %q{Deployments release notes sent via email with Git commits / Pivotal Tracker stories and Campfire notification.}
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_dependency 'capistrano'
|
20
|
+
s.add_dependency 'pivotal-tracker'
|
21
|
+
s.add_dependency 'pony'
|
22
|
+
s.add_dependency 'tinder'
|
23
|
+
s.add_dependency 'activesupport'
|
24
|
+
|
25
|
+
s.add_development_dependency 'rake'
|
26
|
+
s.add_development_dependency 'mocha'
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'dereno'
|
4
|
+
|
5
|
+
class Capistrano::ReleaseNotes
|
6
|
+
def self.load_into(config)
|
7
|
+
config.load do
|
8
|
+
|
9
|
+
namespace :release_notes do
|
10
|
+
|
11
|
+
# rake release_notes:show
|
12
|
+
desc 'Show deployment release notes'
|
13
|
+
task :show, roles: :dereno do
|
14
|
+
Dereno.cap = config
|
15
|
+
puts Dereno.release_notes(true)
|
16
|
+
end
|
17
|
+
|
18
|
+
# rake release_notes:notify
|
19
|
+
desc 'Deployment release notes notification via email (campfire alert in option).'
|
20
|
+
task :notify, roles: :dereno do
|
21
|
+
Dereno.cap = config
|
22
|
+
path = Dereno.build_release_notes(false)
|
23
|
+
Dereno::Campfire.ping if Dereno::Campfire.enabled?
|
24
|
+
|
25
|
+
upload(path, release_path, :via => :scp)
|
26
|
+
run "cd #{release_path}; RAILS_ENV=#{rails_env} bundle exec rake send_email['#{Pathname.new(path).basename.to_s}']"
|
27
|
+
File.delete(path) if File.exists?(path)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
#after 'deploy:restart', 'release_notes:notify'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
if Capistrano::Configuration.instance
|
38
|
+
Capistrano::ReleaseNotes.load_into(Capistrano::Configuration.instance)
|
39
|
+
end
|
data/lib/dereno.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
[
|
4
|
+
'tmpdir',
|
5
|
+
'active_support/core_ext/object/try',
|
6
|
+
'capistrano', 'capistrano/release_notes',
|
7
|
+
'dereno/version', 'dereno/git', 'dereno/pivotal', 'dereno/campfire'
|
8
|
+
].each { |f| require f }
|
9
|
+
|
10
|
+
module Dereno
|
11
|
+
|
12
|
+
require 'dereno/railtie' if defined?(Rails)
|
13
|
+
|
14
|
+
class << self
|
15
|
+
attr_accessor :cap, :local
|
16
|
+
end
|
17
|
+
|
18
|
+
# Build config email file and return the path
|
19
|
+
def self.build_release_notes(local)
|
20
|
+
self.local, path = local, File.join(Dir.tmpdir,'deployment.txt')
|
21
|
+
write_config_file(path)
|
22
|
+
path
|
23
|
+
end
|
24
|
+
|
25
|
+
# Return current deployment release notes
|
26
|
+
def self.release_notes(local)
|
27
|
+
self.local = local
|
28
|
+
body
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def self.subject
|
34
|
+
@cap.dereno_options[:subject] || "[DEPLOY] #{app} (branch #{branch} deployed to #{stage})"
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.body
|
38
|
+
<<-eos
|
39
|
+
#{git_user} deployed #{app} (branch #{branch} to #{stage}), on #{Time.now.strftime("%m/%d/%Y")} at #{Time.now.strftime("%I:%M %p %Z")}
|
40
|
+
|
41
|
+
#{pivotal_stories}
|
42
|
+
#{git_commits}
|
43
|
+
eos
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.app
|
47
|
+
@cap.application.capitalize
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.branch
|
51
|
+
@cap.try(:branch) || 'unknown'
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.stage
|
55
|
+
@cap.try(:stage)
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.commits
|
59
|
+
@commits ||= Dereno::Git.commits
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.pivotal_stories
|
63
|
+
if Dereno::Pivotal.enabled?
|
64
|
+
<<-eos
|
65
|
+
*** Pivotal Tracker Stories ***
|
66
|
+
|
67
|
+
#{Dereno::Pivotal.stories(commits)}
|
68
|
+
eos
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.git_commits
|
73
|
+
<<-eos
|
74
|
+
*** Git Commits ***
|
75
|
+
|
76
|
+
#{commits}
|
77
|
+
eos
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.git_user
|
81
|
+
Dereno::Git.user
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.write_config_file(path)
|
85
|
+
File.open(path, 'w') do |f|
|
86
|
+
f.puts @cap.dereno_options[:from]
|
87
|
+
f.puts @cap.dereno_options[:to]
|
88
|
+
f.puts subject
|
89
|
+
f.puts body
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'tinder'
|
4
|
+
|
5
|
+
module Dereno
|
6
|
+
module Campfire
|
7
|
+
|
8
|
+
def self.config
|
9
|
+
Dereno.cap.try(:dereno_options) && Dereno.cap.dereno_options[:campfire]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.subdomain
|
13
|
+
config && config[:subdomain]
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.token
|
17
|
+
config && config[:token]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.enabled?
|
21
|
+
token && !token.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
# Deployment release notes notification in a Campfire room
|
25
|
+
def self.ping
|
26
|
+
room.speak Dereno.release_notes(false)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def self.campfire
|
32
|
+
Tinder::Campfire.new(subdomain, token: token)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.room
|
36
|
+
campfire.find_room_by_name(config[:room])
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
data/lib/dereno/git.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
module Dereno
|
4
|
+
module Git
|
5
|
+
|
6
|
+
def self.config
|
7
|
+
Dereno.cap
|
8
|
+
end
|
9
|
+
|
10
|
+
# Return all commits since the last deployment
|
11
|
+
def self.commits
|
12
|
+
git_log
|
13
|
+
end
|
14
|
+
|
15
|
+
# Return the user name of the deployer
|
16
|
+
def self.user
|
17
|
+
`git config --get user.name`.strip
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def self.git_previous_revision
|
23
|
+
if Dereno.local
|
24
|
+
config.current_revision[0,7] if config.try(:current_revision)
|
25
|
+
else
|
26
|
+
config.previous_revision[0,7] if config.try(:previous_revision)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.git_current_revision
|
31
|
+
if Dereno.local
|
32
|
+
`git log --pretty=format:'%h' -n 1`
|
33
|
+
else
|
34
|
+
config.current_revision[0,7] if config.try(:current_revision)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.git_log
|
39
|
+
`git log #{git_range} --no-merges --format=format:"%h %s (%an)"` if git_range
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.git_range
|
43
|
+
"#{git_previous_revision}..#{git_current_revision}" if git_previous_revision && git_current_revision
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#@cap.dereno_options[:pivotal_tracker][:token] -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'pivotal-tracker'
|
4
|
+
|
5
|
+
module Dereno
|
6
|
+
module Pivotal
|
7
|
+
|
8
|
+
def self.config
|
9
|
+
Dereno.cap.try(:dereno_options) && Dereno.cap.dereno_options[:pivotal_tracker]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.token
|
13
|
+
config && config[:token]
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.project_id
|
17
|
+
config && config[:project_id]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.enabled?
|
21
|
+
token && !token.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
# Return the stories included in the commits list
|
25
|
+
def self.stories(commits)
|
26
|
+
init_project and pivotal_stories(commits)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def self.line(story, id)
|
32
|
+
"[#{story.story_type.upcase}] #{story.name}, https://www.pivotaltracker.com/story/show/#{id}\n" if story
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.init_project
|
36
|
+
PivotalTracker::Client.token = token
|
37
|
+
@project = PivotalTracker::Project.find(project_id)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.story(id)
|
41
|
+
@project.stories.find(id)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.pivotal_stories(commits)
|
45
|
+
extract_stories(commits).uniq.compact.join("\n")
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.extract_stories(commits)
|
49
|
+
commits.scan(/\d{8}/).map {|id| line(story(id), id)}
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'dereno'
|
4
|
+
require 'rails'
|
5
|
+
require 'pony'
|
6
|
+
|
7
|
+
require 'rake/dsl_definition'
|
8
|
+
include Rake::DSL
|
9
|
+
|
10
|
+
module Dereno
|
11
|
+
def self.email_params(path)
|
12
|
+
params = {}
|
13
|
+
|
14
|
+
File.open(path, 'r') do |f|
|
15
|
+
params[:from] = f.readline.chomp
|
16
|
+
params[:to] = f.readline.chomp
|
17
|
+
params[:subject] = f.readline.chomp
|
18
|
+
params[:body] = f.readlines.join
|
19
|
+
end
|
20
|
+
|
21
|
+
params
|
22
|
+
end
|
23
|
+
|
24
|
+
class Railtie < Rails::Railtie
|
25
|
+
railtie_name :dereno
|
26
|
+
|
27
|
+
rake_tasks do
|
28
|
+
|
29
|
+
# rake send_email['path/to/config_file']
|
30
|
+
desc 'Send an email with params details'
|
31
|
+
task :send_email, :path do |t, args|
|
32
|
+
Pony.mail(Dereno.email_params(args[:path]))
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class TestCampfire < DerenoTestCase
|
6
|
+
|
7
|
+
def setup_campfire
|
8
|
+
@campfire = Tinder::Campfire.new('domain', :token => 'mytoken')
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_config
|
12
|
+
assert_nil Dereno::Campfire.config
|
13
|
+
dereno_setted { assert_equal Dereno.cap.dereno_options[:campfire], Dereno::Campfire.config }
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_subdomain
|
17
|
+
assert_nil Dereno::Campfire.subdomain
|
18
|
+
dereno_setted { assert_equal 'domain', Dereno::Campfire.subdomain }
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_token
|
22
|
+
assert_nil Dereno::Campfire.token
|
23
|
+
dereno_setted { assert_equal 'mytoken', Dereno::Campfire.token }
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_enabled?
|
27
|
+
assert !Dereno::Campfire.enabled?
|
28
|
+
dereno_setted { assert Dereno::Campfire.enabled? }
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_campfire
|
32
|
+
dereno_setted do
|
33
|
+
setup_campfire
|
34
|
+
Dereno::Campfire.expects(:campfire).returns(@campfire)
|
35
|
+
assert_equal @campfire, Dereno::Campfire.campfire
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_room
|
40
|
+
dereno_setted do
|
41
|
+
setup_campfire
|
42
|
+
Dereno::Campfire.expects(:campfire).returns(@campfire)
|
43
|
+
@campfire.expects(:find_room_by_name).returns('First Room')
|
44
|
+
assert_equal 'First Room', Dereno::Campfire.room
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/test/test_dereno.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class TestDereno < DerenoTestCase
|
6
|
+
|
7
|
+
def test_subject
|
8
|
+
dereno_setted { assert_equal '[DEPLOY] App (branch Branch deployed to Staging)', Dereno.subject }
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_body
|
12
|
+
dereno_setted do
|
13
|
+
Dereno.expects(:git_user).returns('Ben')
|
14
|
+
Dereno.expects(:pivotal_stories).returns('')
|
15
|
+
Dereno.expects(:git_commits).returns('')
|
16
|
+
assert Dereno.body.include?('Ben deployed App (branch Branch to Staging)')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_app
|
21
|
+
dereno_setted { assert_equal 'App', Dereno.app }
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_branch
|
25
|
+
assert_equal 'unknown', Dereno.branch
|
26
|
+
dereno_setted { assert_equal 'Branch', Dereno.branch }
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_stage
|
30
|
+
assert_nil Dereno.stage
|
31
|
+
dereno_setted { assert_equal 'Staging', Dereno.stage }
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_commits
|
35
|
+
Dereno::Git.expects(:commits).returns('my commits')
|
36
|
+
assert_equal 'my commits', Dereno.commits
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_git_user
|
40
|
+
Dereno::Git.expects(:user)
|
41
|
+
Dereno.git_user
|
42
|
+
end
|
43
|
+
end
|
data/test/test_git.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require "test_helper"
|
4
|
+
|
5
|
+
class TestGit < DerenoTestCase
|
6
|
+
|
7
|
+
def test_config
|
8
|
+
assert_nil Dereno::Git.config
|
9
|
+
dereno_setted { assert_equal Dereno.cap, Dereno::Git.config }
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_commits
|
13
|
+
Dereno::Git.expects(:git_log)
|
14
|
+
Dereno::Git.commits
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'mocha'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
|
9
|
+
require 'dereno'
|
10
|
+
|
11
|
+
class DerenoTestCase < Test::Unit::TestCase
|
12
|
+
class Cap
|
13
|
+
attr_accessor :application, :branch, :stage, :dereno_options
|
14
|
+
|
15
|
+
def initialize(options)
|
16
|
+
@application = options[:application]
|
17
|
+
@branch = options[:branch]
|
18
|
+
@stage = options[:stage]
|
19
|
+
@dereno_options = options[:dereno_options]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def dereno_setted
|
25
|
+
Dereno.cap = Cap.new({
|
26
|
+
application: 'app',
|
27
|
+
branch: 'Branch',
|
28
|
+
stage: 'Staging',
|
29
|
+
git_user: 'Ben',
|
30
|
+
dereno_options: {
|
31
|
+
campfire: { subdomain: 'domain', token: 'mytoken' , room: 'room' },
|
32
|
+
pivotal_tracker: { token: '1234567890', project_id: 'r2d2' }
|
33
|
+
}
|
34
|
+
})
|
35
|
+
yield
|
36
|
+
Dereno.cap = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
class TestPivotal < DerenoTestCase
|
6
|
+
|
7
|
+
def test_config
|
8
|
+
assert_nil Dereno::Pivotal.config
|
9
|
+
dereno_setted { assert_equal Dereno.cap.dereno_options[:pivotal_tracker], Dereno::Pivotal.config }
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_token
|
13
|
+
assert_nil Dereno::Pivotal.token
|
14
|
+
dereno_setted { assert_equal '1234567890', Dereno::Pivotal.token }
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_project_id
|
18
|
+
assert_nil Dereno::Pivotal.project_id
|
19
|
+
dereno_setted { assert_equal 'r2d2', Dereno::Pivotal.project_id }
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_enabled?
|
23
|
+
assert !Dereno::Pivotal.enabled?
|
24
|
+
dereno_setted { assert Dereno::Pivotal.enabled? }
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_stories_when_no_project
|
28
|
+
commits = ['12345678','12345678','87654321']
|
29
|
+
Dereno::Pivotal.expects(:init_project).returns(nil)
|
30
|
+
Dereno::Pivotal.expects(:pivotal_stories).never
|
31
|
+
Dereno::Pivotal.stories(commits)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_stories_when_project
|
35
|
+
commits = ['12345678','12345678','87654321']
|
36
|
+
Dereno::Pivotal.expects(:init_project).returns(PivotalTracker::Project.new)
|
37
|
+
Dereno::Pivotal.expects(:pivotal_stories).with(commits)
|
38
|
+
Dereno::Pivotal.stories(commits)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_line
|
42
|
+
story = PivotalTracker::Story.new(id:12345678, story_type: 'CHORE', name:'Story name')
|
43
|
+
Dereno::Pivotal.line(story, '12345678')
|
44
|
+
assert_equal "[CHORE] Story name, https://www.pivotaltracker.com/story/show/12345678\n", Dereno::Pivotal.line(story, '12345678')
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_init_project
|
48
|
+
dereno_setted do
|
49
|
+
PivotalTracker::Project.expects(:find).with(Dereno::Pivotal.project_id).returns(true)
|
50
|
+
Dereno::Pivotal.init_project
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_story
|
55
|
+
Dereno::Pivotal.instance_variable_set(:@project, PivotalTracker::Project.new).expects(:stories).returns([])
|
56
|
+
Dereno::Pivotal.story('12345678')
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_pivotal_stories
|
60
|
+
Dereno::Pivotal.stubs(:extract_stories).returns(['12345678','12345678','87654321'])
|
61
|
+
assert_equal "12345678\n87654321", Dereno::Pivotal.pivotal_stories('')
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_extract_stories
|
65
|
+
commits = "[Story #12345678] First commit\n[Story #12345678] Second commit\n[Story #87654321] Last commit"
|
66
|
+
Dereno::Pivotal.stubs(:story).returns(true)
|
67
|
+
Dereno::Pivotal.stubs(:line).returns('story_id')
|
68
|
+
assert_equal ['story_id','story_id','story_id'], Dereno::Pivotal.extract_stories(commits)
|
69
|
+
end
|
70
|
+
end
|
metadata
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dereno
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Colon
|
8
|
+
- Axel Vergult
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-06-21 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: capistrano
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ! '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ! '>='
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: pivotal-tracker
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ! '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: pony
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: tinder
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: activesupport
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rake
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: mocha
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ! '>='
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
description: Deployments release notes sent via email with Git commits / Pivotal Tracker
|
113
|
+
stories and Campfire notification.
|
114
|
+
email:
|
115
|
+
- ben@official.fm
|
116
|
+
- axel@official.fm
|
117
|
+
executables: []
|
118
|
+
extensions: []
|
119
|
+
extra_rdoc_files: []
|
120
|
+
files:
|
121
|
+
- .gitignore
|
122
|
+
- Gemfile
|
123
|
+
- README.md
|
124
|
+
- Rakefile
|
125
|
+
- dereno.gemspec
|
126
|
+
- lib/capistrano/release_notes.rb
|
127
|
+
- lib/dereno.rb
|
128
|
+
- lib/dereno/campfire.rb
|
129
|
+
- lib/dereno/git.rb
|
130
|
+
- lib/dereno/pivotal.rb
|
131
|
+
- lib/dereno/railtie.rb
|
132
|
+
- lib/dereno/version.rb
|
133
|
+
- test/test_campfire.rb
|
134
|
+
- test/test_dereno.rb
|
135
|
+
- test/test_git.rb
|
136
|
+
- test/test_helper.rb
|
137
|
+
- test/test_pivotal.rb
|
138
|
+
homepage: http://official.fm
|
139
|
+
licenses: []
|
140
|
+
metadata: {}
|
141
|
+
post_install_message:
|
142
|
+
rdoc_options: []
|
143
|
+
require_paths:
|
144
|
+
- lib
|
145
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
|
+
requirements:
|
152
|
+
- - ! '>='
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '0'
|
155
|
+
requirements: []
|
156
|
+
rubyforge_project:
|
157
|
+
rubygems_version: 2.0.3
|
158
|
+
signing_key:
|
159
|
+
specification_version: 4
|
160
|
+
summary: Deployments release notes for Rails project using Git
|
161
|
+
test_files:
|
162
|
+
- test/test_campfire.rb
|
163
|
+
- test/test_dereno.rb
|
164
|
+
- test/test_git.rb
|
165
|
+
- test/test_helper.rb
|
166
|
+
- test/test_pivotal.rb
|