heroku-bartender 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/heroku-bartender +1 -1
- data/lib/heroku/bartender.rb +0 -1
- data/lib/heroku/bartender/log.rb +9 -16
- data/lib/heroku/bartender/public/javascript/app.js +36 -0
- data/lib/heroku/bartender/public/stylesheets/application.css +108 -78
- data/lib/heroku/bartender/server.rb +42 -35
- data/lib/heroku/bartender/version.rb +1 -1
- data/lib/heroku/bartender/views/template.erb +21 -20
- metadata +22 -11
- data/lib/heroku/bartender/commit.rb +0 -14
data/bin/heroku-bartender
CHANGED
data/lib/heroku/bartender.rb
CHANGED
data/lib/heroku/bartender/log.rb
CHANGED
@@ -2,23 +2,16 @@ require "grit"
|
|
2
2
|
module Heroku
|
3
3
|
module Bartender
|
4
4
|
class Log
|
5
|
-
|
6
|
-
options
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def self.generate_commits(options = {})
|
14
|
-
get_log(options).map do |item|
|
15
|
-
Commit.new({ :sha => item.sha,
|
16
|
-
:author => item.author.name,
|
17
|
-
:email => item.author.email,
|
18
|
-
:message => item.message,
|
19
|
-
:date => item.date
|
20
|
-
})
|
5
|
+
class << self
|
6
|
+
def get_log(options = {})
|
7
|
+
options[:page] ||= 0
|
8
|
+
offset = options[:max_per_page].to_i * options[:page].to_i
|
9
|
+
Grit::Repo.new('.').commits('master',
|
10
|
+
options[:max_per_page],
|
11
|
+
offset
|
12
|
+
)
|
21
13
|
end
|
14
|
+
alias :generate_commits :get_log
|
22
15
|
end
|
23
16
|
end
|
24
17
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
var deploy = function(sha){
|
3
|
+
$.post("", { 'sha': sha}, function(){
|
4
|
+
isDeploying();
|
5
|
+
});
|
6
|
+
};
|
7
|
+
|
8
|
+
var putOverlay = function(){
|
9
|
+
$("#deploying").overlay().load();
|
10
|
+
};
|
11
|
+
|
12
|
+
var isDeploying = function(){
|
13
|
+
var deploying = false;
|
14
|
+
$.get("/status",function(data){
|
15
|
+
deploying = data["deploying"];
|
16
|
+
if(deploying == true){
|
17
|
+
putOverlay();
|
18
|
+
}
|
19
|
+
});
|
20
|
+
setTimeout("window.location.reload()", 30000);
|
21
|
+
};
|
22
|
+
|
23
|
+
$(function(){
|
24
|
+
$(".build img");
|
25
|
+
$("#deploying").overlay({
|
26
|
+
top: 260,
|
27
|
+
mask: {
|
28
|
+
color: '#fff',
|
29
|
+
loadSpeed: 200,
|
30
|
+
opacity: 0.5
|
31
|
+
},
|
32
|
+
closeOnClick: false,
|
33
|
+
load: false
|
34
|
+
});
|
35
|
+
isDeploying();
|
36
|
+
});
|
@@ -1,150 +1,180 @@
|
|
1
1
|
body {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
background-color: #1F1F1F;
|
3
|
+
height: 100%;
|
4
|
+
font-size: 16px;
|
5
|
+
font-family: Helvetica, Arial, sans-serif;
|
6
6
|
}
|
7
7
|
|
8
8
|
strong {
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
width: 75px;
|
10
|
+
display: block;
|
11
|
+
float: left;
|
12
|
+
font-style: normal;
|
13
13
|
}
|
14
14
|
|
15
15
|
div.container {
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
width: 960px;
|
17
|
+
margin: 0 auto;
|
18
|
+
padding: 1em 1em;
|
19
|
+
background-color: white;
|
20
20
|
}
|
21
21
|
|
22
22
|
div.build {
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
width: 542px;
|
24
|
+
padding: 0.5em;
|
25
|
+
margin-bottom: 1em;
|
26
|
+
border-radius: 5px;
|
27
27
|
}
|
28
28
|
|
29
29
|
div.content {
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
border-radius: 5px;
|
31
|
+
width: 450px;
|
32
|
+
padding: 1em;
|
33
|
+
background-color: white;
|
34
34
|
}
|
35
35
|
|
36
36
|
div.build em {
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
display: block;
|
38
|
+
padding-right: 12px;
|
39
|
+
float: left;
|
40
|
+
font-family: 'Inconsolata', Courier;
|
41
|
+
font-size: 0.9em;
|
42
42
|
}
|
43
43
|
|
44
44
|
div.build h2 {
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
45
|
+
display: block;
|
46
|
+
font-size: 1.75em;
|
47
|
+
margin-bottom: 7px;
|
48
|
+
margin-top: -10px;
|
49
|
+
font-weight: 300;
|
50
|
+
letter-spacing: -2px;
|
51
|
+
font-family: Helvetica;
|
52
52
|
}
|
53
53
|
|
54
54
|
div.build h2 span {
|
55
|
-
|
56
|
-
|
55
|
+
color: #999;
|
56
|
+
float: right;
|
57
57
|
}
|
58
58
|
|
59
59
|
|
60
60
|
div.user-info {
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
margin-top: 15px;
|
62
|
+
width: 414px;
|
63
|
+
height: 60px;
|
64
64
|
}
|
65
65
|
|
66
66
|
div.user-info img {
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
display: block;
|
68
|
+
border: 1px solid black;
|
69
|
+
float: left;
|
70
|
+
height: 50px;
|
71
71
|
|
72
72
|
}
|
73
73
|
|
74
74
|
|
75
75
|
div.user-info p {
|
76
|
-
|
77
|
-
|
76
|
+
float: right;
|
77
|
+
width: 352px;
|
78
78
|
}
|
79
79
|
|
80
80
|
div.user-info p.ago {
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
81
|
+
font-family: "Inconsolata", Courier;
|
82
|
+
font-style: italic;
|
83
|
+
font-size: 0.8em;
|
84
|
+
color: #444;
|
85
|
+
margin-top: 4px;
|
86
86
|
}
|
87
87
|
|
88
88
|
div.actions {
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
width: 450px;
|
90
|
+
clear: both;
|
91
|
+
margin-top: 10px;
|
92
92
|
}
|
93
93
|
|
94
94
|
div.actions span {
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
95
|
+
width: 43px;
|
96
|
+
display: block;
|
97
|
+
line-height: 15px;
|
98
|
+
padding-left: 20px;
|
99
|
+
float: left;
|
100
|
+
height: 15px;
|
101
|
+
font-size: 0.7em;
|
102
102
|
}
|
103
103
|
|
104
104
|
div.actions a {
|
105
|
-
|
106
|
-
|
105
|
+
color: #000;
|
106
|
+
text-decoration: none;
|
107
107
|
}
|
108
108
|
div.actions span:hover {
|
109
|
-
|
109
|
+
text-decoration: underline;
|
110
110
|
}
|
111
111
|
|
112
112
|
div.actions span.build {
|
113
|
-
|
113
|
+
background: url("/images/build.png") no-repeat;
|
114
114
|
}
|
115
115
|
|
116
116
|
div.actions span.deploy {
|
117
|
-
|
117
|
+
background: url("/images/deploy.png") no-repeat;
|
118
118
|
}
|
119
119
|
|
120
120
|
.clear { clear: both; }
|
121
121
|
|
122
122
|
/* Default Box */
|
123
123
|
div.build > div {
|
124
|
-
|
125
|
-
|
124
|
+
border: 1px solid white;
|
125
|
+
box-shadow: 0px 0px 1px black;
|
126
126
|
}
|
127
127
|
|
128
128
|
/* Green Frame */
|
129
129
|
div.ok {
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
130
|
+
-moz-box-shadow: 1px 1px 3px #7fb800;
|
131
|
+
-webkit-box-shadow: 1px 1px 3px #7fb800;
|
132
|
+
box-shadow: 1px 1px 3px #4d7000;
|
133
|
+
background: url("/images/ok.png") 500px 50% no-repeat #96da00;
|
134
134
|
}
|
135
135
|
|
136
136
|
/* Red Frame */
|
137
137
|
div.fail {
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
138
|
+
-moz-box-shadow: 1px 1px 3px #7d0d00;
|
139
|
+
-webkit-box-shadow: 1px 1px 3px #7d0d00;
|
140
|
+
box-shadow: 1px 1px 3px #7d0d00;
|
141
|
+
background: url("/images/fail.png") 500px 50% no-repeat #ff3c26;
|
142
142
|
}
|
143
143
|
|
144
144
|
/* Yellow Frame */
|
145
145
|
div.unknown {
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
}
|
146
|
+
background: url("/images/unknown.png") 500px 50% no-repeat #ffff17;
|
147
|
+
-moz-box-shadow: 1px 1px 3px #9b9b24;
|
148
|
+
-webkit-box-shadow: 1px 1px 3px #9b9b24;
|
149
|
+
box-shadow: 1px 1px 3px #9b9b24;
|
150
|
+
}
|
151
|
+
|
152
|
+
/* Deploying overlay */
|
153
|
+
#deploying {
|
154
|
+
display:none;
|
155
|
+
width:400px;
|
156
|
+
border:10px solid white;
|
157
|
+
border:10px solid rgba(82, 82, 82, 0.698);
|
158
|
+
-moz-border-radius:8px;
|
159
|
+
-webkit-border-radius:8px;
|
160
|
+
}
|
161
|
+
|
162
|
+
#deploying div {
|
163
|
+
padding:10px;
|
164
|
+
border:1px solid black;
|
165
|
+
background-color:#fff;
|
166
|
+
font-family:'Inconsolata', Courier;
|
167
|
+
}
|
168
|
+
|
169
|
+
#deploying h2 {
|
170
|
+
margin:-11px;
|
171
|
+
margin-bottom:0px;
|
172
|
+
color:#999;
|
173
|
+
background-color: #ffff17;
|
174
|
+
padding:5px 10px;
|
175
|
+
border:1px solid black;
|
176
|
+
font-size:20px;
|
177
|
+
}
|
178
|
+
#deploying span {
|
179
|
+
font-size:15px;
|
180
|
+
}
|
@@ -1,16 +1,18 @@
|
|
1
1
|
require 'sinatra/base'
|
2
2
|
require 'erb'
|
3
|
+
require 'json'
|
4
|
+
|
3
5
|
module Heroku
|
4
6
|
module Bartender
|
5
7
|
class Server < Sinatra::Base
|
6
|
-
|
7
|
-
@@deployed_versions = {}
|
8
|
-
@@status = nil
|
9
8
|
@@options = {}
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
configure do
|
11
|
+
dir = File.dirname(File.expand_path(__FILE__))
|
12
|
+
set :views, "#{dir}/views"
|
13
|
+
set :public, "#{dir}/public"
|
14
|
+
set :deployed_versions, {}
|
15
|
+
end
|
14
16
|
|
15
17
|
def self.max_per_page
|
16
18
|
@@options[:commits_per_page]
|
@@ -43,39 +45,40 @@ module Heroku
|
|
43
45
|
def self.predeploy
|
44
46
|
config.predeploy.to_s
|
45
47
|
end
|
46
|
-
|
48
|
+
|
49
|
+
before do
|
50
|
+
@page = params[:page] || 0
|
51
|
+
@commits = Log.generate_commits(params.merge({:max_per_page => Server.max_per_page}))
|
52
|
+
end
|
53
|
+
|
47
54
|
get "/" do
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
)
|
55
|
+
erb :template
|
56
|
+
end
|
57
|
+
|
58
|
+
get "/status" do
|
59
|
+
content_type :json
|
60
|
+
{ deploying: @@deploying }.to_json
|
55
61
|
end
|
56
62
|
|
57
63
|
post "/" do
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
if params[:sha] and not @@deploying
|
65
|
+
@@deploying = true
|
66
|
+
Thread.new do
|
67
|
+
begin
|
68
|
+
Command.move_to params[:sha], predeploy, target
|
69
|
+
deployed_versions[params[:sha]] = [Time.now, true, nil]
|
70
|
+
rescue Exception => e
|
71
|
+
deployed_versions[params[:sha]] = [Time.now, false, e]
|
72
|
+
end
|
73
|
+
@@deploying = false
|
67
74
|
end
|
68
75
|
end
|
69
|
-
erb
|
70
|
-
:current_version => Command.current_version(Server.target),
|
71
|
-
:deployed_versions => @@deployed_versions,
|
72
|
-
:status => @@status,
|
73
|
-
:page => page
|
74
|
-
)
|
76
|
+
erb :template
|
75
77
|
end
|
76
78
|
|
77
79
|
def self.start(options = {})
|
78
80
|
@@options = options
|
81
|
+
@@deploying = false
|
79
82
|
authorize(user, password)
|
80
83
|
run!(:host => host, :port => port)
|
81
84
|
end
|
@@ -90,11 +93,15 @@ module Heroku
|
|
90
93
|
|
91
94
|
helpers do
|
92
95
|
include Rack::Utils
|
93
|
-
|
94
|
-
def
|
95
|
-
|
96
|
+
|
97
|
+
def deploying
|
98
|
+
@@deploying
|
96
99
|
end
|
97
|
-
|
100
|
+
|
101
|
+
def deployed_versions
|
102
|
+
settings.deployed_versions
|
103
|
+
end
|
104
|
+
|
98
105
|
def pagination(page)
|
99
106
|
page = page.to_i
|
100
107
|
if page == 0
|
@@ -107,8 +114,8 @@ module Heroku
|
|
107
114
|
end
|
108
115
|
|
109
116
|
def build_status(version_sha)
|
110
|
-
if
|
111
|
-
status =
|
117
|
+
if deployed_versions[version_sha]
|
118
|
+
status = deployed_versions[version_sha][1]
|
112
119
|
if status == true
|
113
120
|
return 'ok'
|
114
121
|
elsif status == false
|
@@ -8,32 +8,33 @@
|
|
8
8
|
<link href="http://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet" type="text/css">
|
9
9
|
|
10
10
|
<script type="text/javascript" src="/javascript/jquery-1.5.1.min.js"></script>
|
11
|
-
<script
|
12
|
-
|
13
|
-
$(".build img")
|
14
|
-
});
|
15
|
-
var deploy = function(sha){
|
16
|
-
$.post("", { 'sha': sha}, function(){
|
17
|
-
window.location.reload();
|
18
|
-
});
|
19
|
-
};
|
11
|
+
<script src="http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js"></script>
|
12
|
+
<script type="text/javascript" src="/javascript/app.js">
|
20
13
|
</script>
|
21
14
|
</head>
|
22
15
|
<body>
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
16
|
+
<div id="deploying">
|
17
|
+
<div>
|
18
|
+
<h2> Bartender is deploying</h2>
|
19
|
+
<span>This page will automatically refresh</span>
|
20
|
+
</div>
|
21
|
+
</div>
|
27
22
|
<div class="container">
|
28
|
-
<%= pagination(page) %>
|
29
|
-
|
23
|
+
<%= pagination(@page) %>
|
24
|
+
|
25
|
+
<div class="content">
|
26
|
+
<p>Remote: <b><%= target %></b></p>
|
27
|
+
<p>Pre-deploy: <b><%= predeploy %></b></p>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<% @commits.each do |commit| %>
|
30
31
|
<div class="build <%= build_status(commit.sha) %>">
|
31
32
|
<div class="content">
|
32
|
-
<h2><%= commit.message %><span class="commit"><%=commit.sha[0..7]%> </h2>
|
33
|
+
<h2><%= commit.message %><span class="commit"><%= commit.sha[0..7] %> </h2>
|
33
34
|
<div class="user-info">
|
34
|
-
<img src="<%= user_img_url(commit.email) %>"/>
|
35
|
-
<p> <%= commit.author %> </p>
|
36
|
-
<p class="ago"><strong>Committed: </strong><%= commit.date%></p>
|
35
|
+
<img src="<%= user_img_url(commit.author.email) %>"/>
|
36
|
+
<p> <%= commit.author.name %> </p>
|
37
|
+
<p class="ago"><strong>Committed: </strong><%= commit.date %></p>
|
37
38
|
<% if deployed_versions[commit.sha] %>
|
38
39
|
<p class="ago"><strong>Deployed: </strong><%= deployed_versions[commit.sha][0] %></p>
|
39
40
|
<% end %>
|
@@ -45,7 +46,7 @@
|
|
45
46
|
</div>
|
46
47
|
</div>
|
47
48
|
<% end %>
|
48
|
-
<%= pagination(page) %>
|
49
|
+
<%= pagination(@page) %>
|
49
50
|
</div>
|
50
51
|
</body>
|
51
52
|
</html>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heroku-bartender
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-08-
|
12
|
+
date: 2011-08-15 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &2156095960 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,21 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2156095960
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rack-test
|
27
|
+
requirement: &2156095360 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2156095360
|
25
36
|
- !ruby/object:Gem::Dependency
|
26
37
|
name: grit
|
27
|
-
requirement: &
|
38
|
+
requirement: &2156094760 !ruby/object:Gem::Requirement
|
28
39
|
none: false
|
29
40
|
requirements:
|
30
41
|
- - ! '>='
|
@@ -32,10 +43,10 @@ dependencies:
|
|
32
43
|
version: 2.4.1
|
33
44
|
type: :runtime
|
34
45
|
prerelease: false
|
35
|
-
version_requirements: *
|
46
|
+
version_requirements: *2156094760
|
36
47
|
- !ruby/object:Gem::Dependency
|
37
48
|
name: sinatra
|
38
|
-
requirement: &
|
49
|
+
requirement: &2156094120 !ruby/object:Gem::Requirement
|
39
50
|
none: false
|
40
51
|
requirements:
|
41
52
|
- - ! '>='
|
@@ -43,10 +54,10 @@ dependencies:
|
|
43
54
|
version: 1.2.0
|
44
55
|
type: :runtime
|
45
56
|
prerelease: false
|
46
|
-
version_requirements: *
|
57
|
+
version_requirements: *2156094120
|
47
58
|
- !ruby/object:Gem::Dependency
|
48
59
|
name: choice
|
49
|
-
requirement: &
|
60
|
+
requirement: &2156093560 !ruby/object:Gem::Requirement
|
50
61
|
none: false
|
51
62
|
requirements:
|
52
63
|
- - ! '>='
|
@@ -54,7 +65,7 @@ dependencies:
|
|
54
65
|
version: 0.1.4
|
55
66
|
type: :runtime
|
56
67
|
prerelease: false
|
57
|
-
version_requirements: *
|
68
|
+
version_requirements: *2156093560
|
58
69
|
description: Ruby gem to handle releases in heroku.
|
59
70
|
email: sebastianarcila@gmail.com
|
60
71
|
executables:
|
@@ -66,7 +77,6 @@ files:
|
|
66
77
|
- Rakefile
|
67
78
|
- LICENSE
|
68
79
|
- lib/heroku/bartender/command.rb
|
69
|
-
- lib/heroku/bartender/commit.rb
|
70
80
|
- lib/heroku/bartender/config.rb
|
71
81
|
- lib/heroku/bartender/log.rb
|
72
82
|
- lib/heroku/bartender/public/favicon.ico
|
@@ -78,6 +88,7 @@ files:
|
|
78
88
|
- lib/heroku/bartender/public/images/unknown.png
|
79
89
|
- lib/heroku/bartender/public/images/Untitled-6.png
|
80
90
|
- lib/heroku/bartender/public/images/yellow-gradient.png
|
91
|
+
- lib/heroku/bartender/public/javascript/app.js
|
81
92
|
- lib/heroku/bartender/public/javascript/jquery-1.5.1.min.js
|
82
93
|
- lib/heroku/bartender/public/stylesheets/application.css
|
83
94
|
- lib/heroku/bartender/public/stylesheets/reset.css
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module Heroku
|
2
|
-
module Bartender
|
3
|
-
class Commit
|
4
|
-
attr_accessor :sha, :author, :email, :message, :date
|
5
|
-
def initialize(stub = {})
|
6
|
-
@sha = stub[:sha]
|
7
|
-
@author = stub[:author]
|
8
|
-
@email = stub[:email]
|
9
|
-
@message = stub[:message]
|
10
|
-
@date = stub[:date]
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|