heidi 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/Gemfile +1 -0
  2. data/Gemfile.lock +3 -0
  3. data/README.rdoc +20 -0
  4. data/VERSION +1 -1
  5. data/bin/heidi +8 -82
  6. data/heidi.gemspec +49 -10
  7. data/lib/heidi.rb +4 -0
  8. data/lib/heidi/build.rb +42 -10
  9. data/lib/heidi/builder.rb +7 -2
  10. data/lib/heidi/hook.rb +2 -0
  11. data/lib/heidi/integrator.rb +11 -5
  12. data/lib/heidi/project.rb +37 -24
  13. data/lib/heidi/shell.rb +119 -0
  14. data/lib/heidi/tester.rb +6 -5
  15. data/lib/heidi/web.rb +65 -4
  16. data/lib/heidi/web/assets/css/bootstrap-responsive.css +643 -0
  17. data/lib/heidi/web/assets/css/bootstrap.css +3682 -0
  18. data/lib/heidi/web/{public/css/screen.css → assets/css/colors.css} +1 -75
  19. data/lib/heidi/web/assets/css/docs.css +772 -0
  20. data/lib/heidi/web/{public → assets}/images/HeidiBlue-480.png +0 -0
  21. data/lib/heidi/web/{public → assets}/images/HeidiBlue.gif +0 -0
  22. data/lib/heidi/web/{public → assets}/images/OrganisedMinds.png +0 -0
  23. data/lib/heidi/web/{public → assets}/images/heidi.jpeg +0 -0
  24. data/lib/heidi/web/assets/img/glyphicons-halflings-white.png +0 -0
  25. data/lib/heidi/web/assets/img/glyphicons-halflings.png +0 -0
  26. data/lib/heidi/web/assets/img/glyphicons/glyphicons_009_magic.png +0 -0
  27. data/lib/heidi/web/assets/img/glyphicons/glyphicons_042_group.png +0 -0
  28. data/lib/heidi/web/assets/img/glyphicons/glyphicons_079_podium.png +0 -0
  29. data/lib/heidi/web/assets/img/glyphicons/glyphicons_082_roundabout.png +0 -0
  30. data/lib/heidi/web/assets/img/glyphicons/glyphicons_155_show_thumbnails.png +0 -0
  31. data/lib/heidi/web/assets/img/glyphicons/glyphicons_163_iphone.png +0 -0
  32. data/lib/heidi/web/assets/img/glyphicons/glyphicons_214_resize_small.png +0 -0
  33. data/lib/heidi/web/assets/img/glyphicons/glyphicons_266_book_open.png +0 -0
  34. data/lib/heidi/web/assets/js/README.md +106 -0
  35. data/lib/heidi/web/assets/js/application.js +180 -0
  36. data/lib/heidi/web/assets/js/bootstrap-alert.js +94 -0
  37. data/lib/heidi/web/assets/js/bootstrap-button.js +100 -0
  38. data/lib/heidi/web/assets/js/bootstrap-carousel.js +157 -0
  39. data/lib/heidi/web/assets/js/bootstrap-collapse.js +136 -0
  40. data/lib/heidi/web/assets/js/bootstrap-dropdown.js +92 -0
  41. data/lib/heidi/web/assets/js/bootstrap-modal.js +210 -0
  42. data/lib/heidi/web/assets/js/bootstrap-popover.js +95 -0
  43. data/lib/heidi/web/assets/js/bootstrap-scrollspy.js +125 -0
  44. data/lib/heidi/web/assets/js/bootstrap-tab.js +130 -0
  45. data/lib/heidi/web/assets/js/bootstrap-tooltip.js +270 -0
  46. data/lib/heidi/web/assets/js/bootstrap-transition.js +51 -0
  47. data/lib/heidi/web/assets/js/bootstrap-typeahead.js +271 -0
  48. data/lib/heidi/web/assets/js/google-code-prettify/prettify.css +30 -0
  49. data/lib/heidi/web/assets/js/google-code-prettify/prettify.js +28 -0
  50. data/lib/heidi/web/assets/js/jquery.js +9252 -0
  51. data/lib/heidi/web/views/build.erb +40 -24
  52. data/lib/heidi/web/views/commit.erb +10 -7
  53. data/lib/heidi/web/views/config.erb +34 -18
  54. data/lib/heidi/web/views/home.erb +44 -25
  55. data/lib/heidi/web/views/layout.erb +57 -4
  56. data/lib/heidi/web/views/new_project.erb +56 -0
  57. data/lib/heidi/web/views/project.erb +114 -32
  58. data/lib/heidi/web/views/project_header.erb +20 -0
  59. data/spec/heidi/build_spec.rb +163 -2
  60. data/spec/heidi/builder_spec.rb +61 -1
  61. data/spec/heidi/hook_spec.rb +47 -1
  62. data/spec/heidi/integrator_spec.rb +96 -1
  63. data/spec/heidi/project_spec.rb +177 -2
  64. data/spec/heidi/shell_spec.rb +67 -0
  65. data/spec/heidi/web_spec.rb +78 -2
  66. data/spec/heidi_spec.rb +16 -5
  67. data/spec/spec_helper.rb +1 -1
  68. data/spec/support/01_rworld.rb +9 -0
  69. data/spec/support/mock_project.rb +39 -0
  70. data/spec/support/survivable.rb +10 -0
  71. metadata +131 -79
  72. data/spec/heidi/tester_spec.rb +0 -5
@@ -1,29 +1,45 @@
1
- <h1><%= project.name %></h1>
1
+ <%= erb :project_header, :locals => { :project => project } %>
2
2
 
3
- <a href="/projects/<%= project.basename %>"><< back</a>
4
- <br /><br />
3
+ <header class="subhead">
4
+ <div class="subnav">
5
+ <ul class="nav nav-pills">
6
+ <% if build.status == "passed" %>
7
+ <li class="active">
8
+ <a href='/projects/<%= project.basename %>/build/<%= build.commit %>/tar_ball'>download</a>
9
+ </li>
10
+ <% end %>
11
+ <% build.logs.each do |log| %>
12
+ <li><a href="#<%= log.file_name %>"><%= log.file_name %></a></li>
13
+ <% end %>
14
+ </ul>
15
+ </div>
16
+ </header>
5
17
 
6
- <h2 class="<%= build.status %>"><%= build.commit %></h2>
7
- <div class="column">
8
- <% if build.status == "passed" %>
9
- <a href='/projects/<%= project.basename %>/build/<%= build.commit %>/tar_ball'>download</a>
10
- <br /><br />
11
- <% end %>
18
+ <section id="details">
19
+ <div class="row">
20
+ <div class="span9">
21
+ <h2 class="<%= build.status %>">Build <%= build.commit %></h2>
22
+ <br />
23
+ <br />
24
+ </div>
25
+ <div class="span3">
26
+ <a href="/projects/<%= project.basename %>/commit/<%= build.commit %>">Want to see the commit?</a>
27
+ </div>
28
+ </div>
29
+ </section>
12
30
 
13
- | <% build.logs.each do |log| %>
14
- <a href="#<%= log.file_name %>"><%= log.file_name %></a> |
15
- <% end %>
16
- </div>
17
- <div class="column">
18
- <a href="/projects/<%= project.basename %>/commit/<%= build.commit %>">Want to see the commit?</a>
19
- </div>
20
- <br class="clear" />
21
- <br />
22
- <br />
23
31
 
24
- <% build.logs.each do |log| %>
25
- <h3 class="log"><%= log.file_name %></h3>
26
- <a name="<%= log.file_name %>" href="#top" class="top">top</a>
32
+
33
+ <section id="logs">
34
+ <% build.logs.each do |log| %>
35
+ <div class="row">
36
+ <div class="span11">
37
+ <h3 class="log"><%= log.file_name %></h3>
38
+ </div>
39
+ <div class="span1">
40
+ <a name="<%= log.file_name %>" href="#top" class="top">^^ top</a>
41
+ </div>
42
+ </div>
27
43
  <pre class="terminal"><%= ansi_color_codes(h(log.contents)) %></pre>
28
- <% end %>
29
- <br /><br />
44
+ <% end %>
45
+ </section>
@@ -1,10 +1,13 @@
1
- <h1><%= project.name %></h1>
1
+ <%= erb :project_header, :locals => { :project => project } %>
2
2
 
3
- <a href="/projects/<%= project.basename %>"><< back</a>
4
- <br /><br />
3
+ <section id="commit">
4
+ <div class="row">
5
+ <div class="span12">
6
+ <h2><%= commit %></h2>
5
7
 
6
- <h2><%= commit %></h2>
8
+ <pre class="terminal"><%= ansi_color_codes(h(stat)) %>
7
9
 
8
- <pre class="terminal"><%= ansi_color_codes(h(stat)) %>
9
-
10
- <%= ansi_color_codes(h(diff)) %></pre>
10
+ <%= ansi_color_codes(h(diff)) %></pre>
11
+ </div>
12
+ </div>
13
+ </section>
@@ -1,21 +1,37 @@
1
- <h1>Configure <%= project.name %></h1>
1
+ <%= erb :project_header, :locals => { :project => project } %>
2
2
 
3
- <form method="POST" action="/projects/<%= project.basename %>">
4
- <label for="name">Name</label>
5
- <input type="text" name="name" value="<%= project.name %>" />
6
- <br />
7
- <br />
3
+ <section id="config">
4
+ <h2>Configuration</h2>
8
5
 
9
- <label for="branch">Integration branch</label>
10
- <select name="branch">
11
- <option value="">...</option>
12
- <% project.integration_branches.each do |branch| %>
13
- <% branch_name = branch.split("/").last %>
14
- <option value="<%= branch_name %>" <%= "selected" if branch_name == project.integration_branch %>><%= branch %></option>
15
- <% end %>
16
- </select>
6
+ <div class="well">
7
+ <form method="POST" action="/projects/<%= project.basename %>">
8
+ <div class="field">
9
+ <label for="name">Name</label>
10
+ <input type="text" name="name" value="<%= project.name %>" />
11
+ </div>
17
12
 
18
- <br />
19
- <br />
20
- <input type="submit" />
21
- </form>
13
+ <div class="field">
14
+ <label for="branch">Integration branch</label>
15
+ <select name="branch">
16
+ <option value="">...</option>
17
+ <% project.integration_branches.each do |branch| %>
18
+ <% branch_name = branch.gsub("origin/", "") %>
19
+ <option value="<%= branch_name %>" <%= "selected" if branch_name == project.branch %>><%= branch %></option>
20
+ <% end %>
21
+ </select>
22
+ </div>
23
+
24
+ <br />
25
+ <div class="btn-toolbar">
26
+ <div class="btn-group">
27
+ <a class="btn" href="/projects/<%= project.basename %>">&laquo; Cancel</a>
28
+ <button class="btn" name="reset" type="reset" value="0">Reset</button>
29
+ </div>
30
+
31
+ <div class="btn-group">
32
+ <button class="btn btn-success" name="submit" type="submit" value="1">Save &raquo;</button>
33
+ </div>
34
+ </div>
35
+ </form>
36
+ </div>
37
+ </section>
@@ -1,32 +1,51 @@
1
- <div class="column">
2
- <h1>Projects</h1>
3
- <ul class="projects">
4
- <% projects.each do |project| %>
5
- <li class="<%= project.build_status %>">
6
- <a href="/projects/<%= project.basename %>"><%= project.name %></a>
7
- - <%= project.build_status %>
8
- </li>
9
- <% end %>
10
- </ul>
1
+ <style>
2
+ ul.projects li { margin-bottom: 5px; }
3
+ ul.projects li a { display: inline-block; min-width: 120px; }
4
+ </style>
5
+ <div class="hero-unit">
6
+ <h1>Welcome to Heidi!</h1>
7
+ <p>A simple, naive, yet powerful Continious Integration ... thingy...</p>
8
+ <p><a href="https://github.com/OrganisedMinds/heidi/blob/develop/README.rdoc" class="btn btn-primary btn-large">Learn more &raquo;</a></p>
11
9
  </div>
12
10
 
13
- <div class="column" style="width: 500px;">
14
- <img src='/images/HeidiBlue-480.png' />
15
- <br /><br />
11
+ <section>
12
+ <div class="row">
13
+ <div class="span4">
14
+ <h2>Projects</h2>
15
+ <ul class="projects">
16
+ <% projects.sort_by(&:basename).each do |project| %>
17
+ <li class="<%= project.build_status %>">
18
+ <a href="/projects/<%= project.basename %>"><%= project.name %></a>
19
+ <span class="label <%= status2label(project.build_status) %>"><%= project.build_status.empty? ? "unknown" : project.build_status %></span>
20
+ </li>
21
+ <% end %>
22
+ </ul>
23
+ <br />
24
+ <a href="/projects/" class="btn btn-success"><strong>+</strong> &nbsp;new project</a>
25
+ </div>
16
26
 
17
- <p>Heidi is OpenSource. Fork, patch and improve it at <a
18
- href="https://github.com/coffeeaddict/heidi">GitHub</a></p>
27
+ <div class="span4">
28
+ <h2>About Heidi!</h2>
29
+ <p>Heidi is OpenSource. Fork, patch and improve it at <a
30
+ href="https://github.com/OrganisedMinds/heidi">GitHub</a></p>
19
31
 
20
- <p>Heidi is proudly sponsored by <a
21
- href="http://organisedminds.com">organisedminds.com</a> (a super useful
22
- flexible tool for collaborating in teams and projects across geographic
23
- locations) Check it out!</p>
32
+ <p>Heidi is proudly sponsored by <a
33
+ href="http://organisedminds.com">organisedminds.com</a> (a super useful
34
+ flexible tool for collaborating in teams and projects across geographic
35
+ locations) Check it out!</p>
24
36
 
25
- <br /><br />
26
- <center>
27
- <a href="http://organisedminds.com" title="Sponsored by OrganisedMinds.com">
28
- <img src="/images/OrganisedMinds.png" alt="OrganisedMinds.com" />
29
- </a>
30
- </center>
37
+ <br /><br />
38
+ <center>
39
+ <a href="http://organisedminds.com" title="Sponsored by OrganisedMinds.com">
40
+ <img src="/images/OrganisedMinds.png" alt="OrganisedMinds.com" />
41
+ </a>
42
+ </center>
43
+ </div>
31
44
 
45
+ <div class="span4">
46
+ <div class="thumbnail">
47
+ <img src='/images/HeidiBlue-480.png' alt="Heidi!, artist & copyrights unknown"/>
48
+ </div>
49
+ </div>
32
50
  </div>
51
+ </section>
@@ -1,13 +1,66 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
- <link rel="stylesheet" media="screen" href="/css/screen.css" />
5
- <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
4
+ <meta charset="utf-8">
6
5
  <title>Heidi!</title>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <meta name="description" content="">
8
+ <meta name="author" content="">
9
+
10
+ <!-- Le styles -->
11
+ <link href="/css/bootstrap.css" rel="stylesheet">
12
+ <style>
13
+ body {
14
+ padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
15
+ }
16
+ section {
17
+ padding-bottom: 20px;
18
+ }
19
+ </style>
20
+ <link href="/css/bootstrap-responsive.css" rel="stylesheet">
21
+ <link href="/css/colors.css" rel="stylesheet">
22
+
23
+ <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
24
+ <!--[if lt IE 9]>
25
+ <script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
26
+ <![endif]-->
27
+
28
+ <!-- Le fav and touch icons -->
29
+ <link rel="shortcut icon" href="/images/favicon.ico">
7
30
  </head>
31
+
8
32
  <body>
33
+
34
+ <div class="navbar navbar-fixed-top">
35
+ <div class="navbar-inner">
36
+ <div class="container">
37
+ <a class="brand" href="/">Heidi!</a>
38
+ </div>
39
+ </div>
40
+ </div>
41
+
9
42
  <div class="container">
43
+ <%= breadcrumbs %>
10
44
  <%= yield %>
11
- </div>
45
+
46
+ </div> <!-- /container -->
47
+
48
+ <!-- Le javascript
49
+ ================================================== -->
50
+ <!-- Placed at the end of the document so the pages load faster -->
51
+ <script src="/js/jquery.js"></script>
52
+ <script src="/js/bootstrap-transition.js"></script>
53
+ <script src="/js/bootstrap-alert.js"></script>
54
+ <script src="/js/bootstrap-modal.js"></script>
55
+ <script src="/js/bootstrap-dropdown.js"></script>
56
+ <script src="/js/bootstrap-scrollspy.js"></script>
57
+ <script src="/js/bootstrap-tab.js"></script>
58
+ <script src="/js/bootstrap-tooltip.js"></script>
59
+ <script src="/js/bootstrap-popover.js"></script>
60
+ <script src="/js/bootstrap-button.js"></script>
61
+ <script src="/js/bootstrap-collapse.js"></script>
62
+ <script src="/js/bootstrap-carousel.js"></script>
63
+ <script src="/js/bootstrap-typeahead.js"></script>
64
+
12
65
  </body>
13
66
  </html>
@@ -0,0 +1,56 @@
1
+ <header>
2
+ <div class="row">
3
+ <div class="span9">
4
+ <h1>New Project</h1>
5
+ </div>
6
+ <div class="span3">
7
+ <ul class="nav nav-list">
8
+ <li>
9
+ <a href="/"><i class="icon-home"></i>Home</a>
10
+ </li>
11
+ </ul>
12
+ </div>
13
+ </div>
14
+ </header>
15
+
16
+ <br />
17
+ <section id="form">
18
+ <div class="row">
19
+ <div class="span12 well">
20
+ <div class="alert alert-error">
21
+ <strong>Attention! Attention!</strong><br />
22
+ The new-project-over-web feature is 'highly expirimental' at best.<br />
23
+ Best results are obtained with small repos
24
+ </div>
25
+ <br />
26
+
27
+ <form method="post" action="/projects/">
28
+ <div class="field">
29
+ <label for="name">Name</label>
30
+ <input type="text" name="name" id="name" value="" />
31
+ </div>
32
+ <div class="field">
33
+ <label for="origin">Origin</label>
34
+ <input type="text" name="origin" id="origin" value="" />
35
+ </div>
36
+ <div class="field">
37
+ <label for="branch">Branch</label>
38
+ <input type="text" name="branch" id="branch" value="master" />
39
+ </div>
40
+
41
+ <br />
42
+ <div class="btn-toolbar">
43
+ <div class="btn-group">
44
+ <a class="btn" href="/">&laquo; Cancel</a>
45
+ <button class="btn" name="reset" type="reset" value="0">Reset</button>
46
+ </div>
47
+
48
+ <div class="btn-group">
49
+ <button class="btn btn-success" name="submit" type="submit" value="1">Save &raquo;</button>
50
+ </div>
51
+ </div>
52
+ </form>
53
+
54
+ </div>
55
+ </div>
56
+ </section>
@@ -1,37 +1,119 @@
1
- <h1><%= project.name %></h1>
2
-
3
- <a href="/"><< back</a><br /><br />
4
- <h2 class="<%= project.build_status %>"><%= project.build_status %></h2>
5
-
6
- <%
7
- builds = project.builds
8
- current = builds.select { |b| b.commit == project.current_build }.first
9
- latest = builds.select { |b| b.commit == project.latest_build }.first
10
- %>
11
-
12
- <div class="column">
13
- <h2>Overview</h2>
14
- <strong class="label">Current</strong> :
15
- <% unless current.nil? %>
16
- <a class="<%= current.status %>" href="/projects/<%= project.basename %>/build/<%= current.commit %>"><%= current.commit %></a>
17
- <% end %>
1
+ <%= erb :project_header, :locals => { :project => project } %>
2
+
3
+ <br />
4
+ <section id="details">
5
+ <div class="row">
6
+ <div class="alert <%= status2alert(project.build_status) %> span11">
7
+ Build status: <strong><%= project.build_status %></strong>
8
+ </div>
9
+ </div>
10
+
11
+ <%
12
+ builds = project.builds
13
+ current = builds.select { |b| b.commit == project.current_build }.first
14
+ latest = builds.select { |b| b.commit == project.latest_build }.first
15
+ %>
16
+
18
17
  <br />
19
- <strong class="label">Latest successful</strong> :
20
- <% unless latest.nil? %>
21
- <a class="<%= latest.status %>" href="/projects/<%= project.basename %>/build/<%= latest.commit %>"><%= latest == current ? "current" : latest.commit %></a>
22
- <% end %>
18
+ <div class="row">
19
+ <div class="span6">
20
+ <h2>Overview</h2>
21
+ </div>
22
+ </div>
23
+ <div class="row">
24
+ <div class="span6 well">
25
+ <% if project.locked? %>
26
+ <span class="label label-warning">Locked</span>
27
+ <br /><br />
28
+ <% end %>
29
+ <div class="row" style="padding-bottom: 5px">
30
+ <div class="span2"><strong>Current</strong></div>
31
+ <div class="span2">
32
+ <% unless current.nil? %>
33
+ <a href="/projects/<%= project.basename %>/build/<%= current.commit %>">
34
+ <span class="label <%= status2label(current.status) %>">
35
+ <%= current.commit %>
36
+ </span>
37
+ </a>
38
+ <% end %>
39
+ </div>
40
+ </div>
41
+
42
+
43
+ <div class="row" style="padding-bottom: 5px">
44
+ <div class="span2"><strong>Last successful</strong></div>
45
+ <div class="span2">
46
+ <% unless latest.nil? %>
47
+ <a href="/projects/<%= project.basename %>/build/<%= latest.commit %>">
48
+ <span class="label <%= status2label(latest.status) %>">
49
+ <%= latest == current ? "Current" : latest.commit %>
50
+ </span>
51
+ </a>
52
+ <% end %>
53
+ </div>
54
+ </div>
55
+
56
+ <div class="row">
57
+ <div class="span2"><strong>Integration branch</strong></div>
58
+ <div class="span4">
59
+ <span class="label label-info"><%= project.branch %></span>
60
+ <a class="pull-right btn btn-success" href="/projects/<%= project.basename %>/fetch">Fetch & Integrate</a>
61
+ </div>
62
+ </div>
63
+
64
+ </div>
65
+
66
+ </div>
67
+ </section>
68
+
69
+ <section id="history">
23
70
  <br />
24
- <strong class="label">Integration branch</strong> :
25
- <%= project.integration_branch %>
71
+ <h2>Build history</h2>
72
+
26
73
  <br />
27
- </div>
28
- <div class="column">
29
- <a href="/projects/<%= project.basename %>/configure">Configure <%= project.name %></a>
30
- </div>
31
- <br class="clear"/>
32
- <br />
33
- <br />
34
74
 
35
- <h2>Build history</h2>
36
- <pre class="history terminal"><% project.log.each do |line| %><% build = nil %><%= ansi_color_codes line[:graph] %><% unless line[:commit].nil? %><a href="/projects/<%= project.basename %>/commit/<%= line[:commit] %>"><%= line[:commit] %></a><% if (build = line[:build]) %><a class="build" href="/projects/<%= project.basename %>/build/<%= build.commit %>"><%= ansi_color_codes(line[:message]) %></a> <span class="status">[<span class="<%= build.status %>"><%= build.status %></span>] (<%= build.date %>, <%= build.author.gsub '<', '&lt;' %>)</span><% else %><%= ansi_color_codes line[:message] %><% end %><% end %>
75
+ <div class="row">
76
+ <div class="span12">
77
+ <ul class="nav nav-tabs">
78
+ <li class="active"><a href="#gitlog" data-toggle="tab">Git log</a></li>
79
+ <li><a href="#buildlist" data-toggle="tab">Builds list</a></li>
80
+ </ul>
81
+
82
+ <div class="tab-content">
83
+ <div class="tab-pane active" id="gitlog">
84
+ <pre class="terminal"><% project.log.each do |line| %><% build = nil %><%= ansi_color_codes line[:graph] %><% unless line[:commit].nil? %><a href="/projects/<%= project.basename %>/commit/<%= line[:commit] %>"><%= line[:commit] %></a><% if (build = line[:build]) %><a class="build" href="/projects/<%= project.basename %>/build/<%= build.commit %>"><%= ansi_color_codes(line[:message]) %></a> <span class="status">[<span class="<%= build.status %>"><%= build.status %></span>] (<%= build.date %>, <%= build.author.gsub '<', '&lt;' %>)</span><% else %><%= ansi_color_codes line[:message] %><% end %><% end %>
37
85
  <% end %></pre>
86
+ </div>
87
+ <div class="tab-pane" id="buildlist">
88
+ <div class="accordion" id="build_accordion">
89
+ <% project.builds.sort_by(&:time).reverse.each do |build| %>
90
+ <div class="accordion-group">
91
+ <div class="accordion-heading">
92
+ <a class="pull-left accordion-toggle" data-toggle="collapse" data-parent="#build_accordion" href="#<%= build.commit %>"><%= build.commit %></a>
93
+ <span class="pull-left label <%= status2label(build.status) %>" style="margin-top: 5px"><%= build.status %></span>
94
+ <br class="clear" />
95
+ </div>
96
+ <div id="<%= build.commit %>" class="accordion-body collapse">
97
+ <div class='accordion-inner'>
98
+ <%= build.message.gsub("\n", '<br />') %>
99
+ <br />
100
+
101
+ <strong>Author</strong>: <%= build.author %><br />
102
+ <strong>Date</strong>: <%= build.date %><br />
103
+ <br />
104
+ <div class="btn-group">
105
+ <a class="btn" href="/projects/<%= project.basename %>/build/<%= build.commit %>">Open</a>
106
+ <% if !build.tar_ball.nil? %>
107
+ <a class="btn btn-info" href="/projects/<%= project.basename %>/build/<%= build.commit %>/tar_ball">Download</a>
108
+ <% end %>
109
+ </div>
110
+ </div>
111
+ </div>
112
+ </div>
113
+ <% end %>
114
+ </div>
115
+ </div>
116
+ </div>
117
+ </div>
118
+ </div>
119
+ </section>