houston-core 0.5.6 → 0.6.0

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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +94 -69
  3. data/app/adapters/houston/adapters/deployment/engineyard.rb +4 -3
  4. data/app/adapters/houston/adapters/version_control/git_adapter.rb +36 -42
  5. data/app/adapters/houston/adapters/version_control/git_adapter/github_repo.rb +2 -2
  6. data/app/adapters/houston/adapters/version_control/git_adapter/remote_repo.rb +23 -11
  7. data/app/adapters/houston/adapters/version_control/git_adapter/repo.rb +18 -8
  8. data/app/adapters/houston/adapters/version_control/null_repo.rb +8 -0
  9. data/app/assets/javascripts/core/handlebars_helpers.coffee +3 -3
  10. data/app/assets/stylesheets/application/github_repos.scss +77 -0
  11. data/app/assets/stylesheets/application/navigation.scss +2 -0
  12. data/app/assets/stylesheets/application/pull_requests.scss +44 -58
  13. data/app/assets/stylesheets/core/avatars.scss +5 -0
  14. data/app/assets/stylesheets/core/colors.scss.erb +10 -7
  15. data/app/concerns/commit_synchronizer.rb +3 -0
  16. data/app/controllers/github/pulls_controller.rb +12 -0
  17. data/app/controllers/project_tests_controller.rb +3 -3
  18. data/app/controllers/projects_controller.rb +45 -1
  19. data/app/controllers/releases_controller.rb +42 -26
  20. data/app/helpers/application_helper.rb +8 -0
  21. data/app/helpers/avatar_helper.rb +2 -2
  22. data/app/helpers/commit_helper.rb +2 -2
  23. data/app/helpers/oembed_helper.rb +8 -0
  24. data/app/helpers/project_helper.rb +4 -5
  25. data/app/helpers/release_helper.rb +11 -0
  26. data/app/helpers/timeline_helper.rb +1 -1
  27. data/app/helpers/url_helper.rb +0 -18
  28. data/app/interactors/cache_key_dependencies.rb +28 -0
  29. data/app/jobs/sync_all_tickets_job.rb +1 -0
  30. data/app/mailers/view_mailer.rb +0 -1
  31. data/app/models/commit.rb +1 -1
  32. data/app/models/github/pull_request.rb +82 -26
  33. data/app/models/github/pull_request_event.rb +2 -2
  34. data/app/models/milestone.rb +1 -0
  35. data/app/models/project.rb +14 -0
  36. data/app/models/project_dependencies.rb +5 -3
  37. data/app/models/task.rb +1 -1
  38. data/app/models/user.rb +41 -0
  39. data/app/views/commits/show.html.erb +9 -1
  40. data/app/views/github/pulls/index.html.erb +102 -0
  41. data/app/views/project_notification/new_release.html.erb +6 -0
  42. data/app/views/project_tickets/index.xls.erb +0 -7
  43. data/app/views/projects/_form.html.erb +29 -17
  44. data/app/views/projects/index.html.erb +3 -3
  45. data/app/views/projects/new_from_github.html.erb +67 -0
  46. data/app/views/releases/_commits.html.erb +1 -1
  47. data/app/views/releases/show.html.erb +9 -0
  48. data/app/views/users/_form.html.erb +35 -19
  49. data/config/application.rb +12 -0
  50. data/config/initializers/mime_types.rb +1 -0
  51. data/config/routes.rb +17 -3
  52. data/db/migrate/20151201042126_require_projects_to_have_name_and_slug.rb +6 -0
  53. data/db/migrate/20151202005557_add_head_sha_to_projects.rb +24 -0
  54. data/db/migrate/20151202011812_require_projects_to_have_color.rb +13 -0
  55. data/db/migrate/20151205204922_require_project_slugs_to_be_unique.rb +5 -0
  56. data/db/migrate/20151205214647_add_avatar_url_to_pull_requests.rb +5 -0
  57. data/db/migrate/20151209004458_add_json_labels_to_pull_requests.rb +5 -0
  58. data/db/migrate/20151209030113_add_timestamps_to_pull_requests.rb +6 -0
  59. data/db/structure.sql +31 -5
  60. data/houston.gemspec +7 -7
  61. data/lib/configuration.rb +3 -2
  62. data/lib/houston/version.rb +1 -1
  63. data/lib/rack/oembed.rb +23 -0
  64. data/templates/new-instance/config/jobs/cache_key_dependencies.rb +3 -0
  65. data/templates/new-instance/config/triggers/tests/slack_when_analyzed.rb +1 -4
  66. data/templates/new-instance/config/triggers/tests/slack_when_completed.rb +1 -1
  67. data/templates/new-instance/lib/slack_helpers.rb +1 -1
  68. data/test/integration/ticket_tasks_api_test.rb +1 -1
  69. data/test/unit/adapters/git_adapter_test.rb +29 -8
  70. data/test/unit/adapters/version_control_adapters_api_test.rb +2 -0
  71. data/test/unit/controllers/hooks_controller_test.rb +4 -4
  72. data/test/unit/models/commit_test.rb +2 -2
  73. data/test/unit/models/project_test.rb +2 -2
  74. data/test/unit/models/pull_request_test.rb +9 -4
  75. data/test/unit/models/task_test.rb +1 -1
  76. data/test/unit/models/ticket_test.rb +1 -1
  77. metadata +31 -16
@@ -6,7 +6,7 @@ module Houston
6
6
 
7
7
 
8
8
  def project_url
9
- location.to_s
9
+ location
10
10
  .gsub(/^git@(?:www\.)?github.com:/, "https://github.com/")
11
11
  .gsub(/^git:/, "https:")
12
12
  .gsub(/\.git$/, "")
@@ -28,7 +28,7 @@ module Houston
28
28
  end
29
29
 
30
30
  def repo_name
31
- location.path[0...-4]
31
+ Addressable::URI.parse(location).path[0...-4].gsub(/^\//, "")
32
32
  end
33
33
 
34
34
 
@@ -6,9 +6,10 @@ module Houston
6
6
  RETRY_COOLDOWN = 4 # seconds
7
7
 
8
8
 
9
- def initialize(connection, location)
10
- super(connection)
11
- @location = location
9
+
10
+ def initialize(git_path, location)
11
+ super location
12
+ @git_path = git_path.to_s
12
13
  @branch_location = :remote
13
14
  end
14
15
 
@@ -17,8 +18,6 @@ module Houston
17
18
  # Public API for a VersionControl::Adapter Repo
18
19
  # ------------------------------------------------------------------------- #
19
20
 
20
- attr_reader :location
21
-
22
21
  def refresh!(async: false)
23
22
  return clone!(async: async) unless exists?
24
23
  pull!(async: async)
@@ -26,14 +25,14 @@ module Houston
26
25
 
27
26
  # ------------------------------------------------------------------------- #
28
27
 
29
- def to_s
30
- location.to_s
31
- end
32
28
 
33
29
 
30
+ def git_path
31
+ @git_path
32
+ end
34
33
 
35
34
  def clone!(async: false)
36
- GitAdapter.clone!(location, connection.path, async: false)
35
+ async ? Houston.async { _clone!(true) } : _clone!(false)
37
36
  end
38
37
 
39
38
  def pull!(async: false)
@@ -48,6 +47,11 @@ module Houston
48
47
 
49
48
  protected
50
49
 
50
+ def connect!
51
+ clone! unless exists?
52
+ super
53
+ end
54
+
51
55
  def find_commit(sha)
52
56
  pull_and_retry { super(sha) }
53
57
  end
@@ -71,8 +75,16 @@ module Houston
71
75
  end
72
76
  end
73
77
 
78
+ def _clone!(async)
79
+ Houston.benchmark("[git:clone#{":async" if async}] #{location} => #{git_path}") do
80
+ Rugged::Repository.clone_at location, git_path,
81
+ credentials: GitAdapter.credentials,
82
+ bare: true
83
+ end
84
+ end
85
+
74
86
  def _pull!(async)
75
- Houston.benchmark("[git:pull#{":async" if async}] #{connection.path}") do
87
+ Houston.benchmark("[git:pull#{":async" if async}] #{location} => #{git_path}") do
76
88
  options = {credentials: GitAdapter.credentials}
77
89
 
78
90
  # Fetch
@@ -114,7 +126,7 @@ module Houston
114
126
  end
115
127
  rescue
116
128
  $!.additional_information[:repo] = to_s
117
- $!.additional_information[:path] = connection.path
129
+ $!.additional_information[:path] = git_dir
118
130
  raise
119
131
  ensure
120
132
  close
@@ -5,10 +5,12 @@ module Houston
5
5
  module VersionControl
6
6
  class GitAdapter
7
7
  class Repo
8
+ attr_reader :location
8
9
 
9
10
 
10
- def initialize(connection)
11
- @connection = connection
11
+
12
+ def initialize(location)
13
+ @location = location.to_s
12
14
  @branch_location = :local
13
15
  end
14
16
 
@@ -70,10 +72,6 @@ module Houston
70
72
  raise
71
73
  end
72
74
 
73
- def location
74
- connection.path
75
- end
76
-
77
75
  def native_commit(sha)
78
76
  return NullCommit.new if sha == Houston::NULL_GIT_COMMIT
79
77
  to_commit find_commit(sha)
@@ -92,7 +90,7 @@ module Houston
92
90
  end
93
91
 
94
92
  def exists?
95
- File.exists?(connection.path)
93
+ File.exists?(git_path)
96
94
  end
97
95
 
98
96
  # ------------------------------------------------------------------------- #
@@ -130,6 +128,10 @@ module Houston
130
128
  DiffChanges.new `git --git-dir=#{git_dir} diff --name-status #{old_sha} #{new_sha}`
131
129
  end
132
130
 
131
+ def git_path
132
+ location
133
+ end
134
+
133
135
  def to_s
134
136
  location
135
137
  end
@@ -164,7 +166,15 @@ module Houston
164
166
 
165
167
  protected
166
168
 
167
- attr_reader :connection, :branch_location
169
+ attr_reader :branch_location
170
+
171
+ def connection
172
+ @connection ||= connect!
173
+ end
174
+
175
+ def connect!
176
+ Rugged::Repository.new(git_path)
177
+ end
168
178
 
169
179
  def find_commit(sha)
170
180
  normalize_sha!(sha)
@@ -31,6 +31,10 @@ module Houston
31
31
  []
32
32
  end
33
33
 
34
+ def branch(name)
35
+ nil
36
+ end
37
+
34
38
  def commits_between(sha1, sha2)
35
39
  []
36
40
  end
@@ -50,6 +54,10 @@ module Houston
50
54
  def refresh!(async: false)
51
55
  end
52
56
 
57
+ def exists?
58
+ false
59
+ end
60
+
53
61
  # ------------------------------------------------------------------------- #
54
62
 
55
63
 
@@ -74,17 +74,17 @@ Handlebars.registerHelper 'linkToCommit', (commit)->
74
74
 
75
75
  Handlebars.registerHelper 'testerAvatar', (email, size, title)->
76
76
  tester = window.testers.findByEmail(email)
77
- gravatarUrl = "//www.gravatar.com/avatar/#{MD5(email.toLowerCase().trim())}?r=g&d=retro&s=#{size * 2}"
77
+ gravatarUrl = "https://www.gravatar.com/avatar/#{MD5(email.toLowerCase().trim())}?r=g&d=retro&s=#{size * 2}"
78
78
  "<img src=\"#{gravatarUrl}\" width=\"#{size}\" height=\"#{size}\" rel=\"tooltip\" title=\"#{tester.get('name')}\" />"
79
79
 
80
80
  Handlebars.registerHelper 'userAvatar', (size)->
81
81
  user = window.user
82
- gravatarUrl = "//www.gravatar.com/avatar/#{MD5(user.get('email').toLowerCase().trim())}?r=g&d=retro&s=#{size * 2}"
82
+ gravatarUrl = "https://www.gravatar.com/avatar/#{MD5(user.get('email').toLowerCase().trim())}?r=g&d=retro&s=#{size * 2}"
83
83
  "<img src=\"#{gravatarUrl}\" width=\"#{size}\" height=\"#{size}\" rel=\"tooltip\" title=\"#{user.get('name')}\" />"
84
84
 
85
85
  Handlebars.registerHelper 'avatar', (email, size, title)->
86
86
  return "<img class=\"avatar avatar-empty\" width=\"#{size}\" height=\"#{size}\" />" unless email
87
- gravatarUrl = "//www.gravatar.com/avatar/#{MD5(email.toLowerCase().trim())}?r=g&d=retro&s=#{size * 2}"
87
+ gravatarUrl = "https://www.gravatar.com/avatar/#{MD5(email.toLowerCase().trim())}?r=g&d=retro&s=#{size * 2}"
88
88
  if title
89
89
  "<img src=\"#{gravatarUrl}\" class=\"avatar\" width=\"#{size}\" height=\"#{size}\" rel=\"tooltip\" title=\"#{title}\" />"
90
90
  else
@@ -0,0 +1,77 @@
1
+ #repos {
2
+ margin: 0;
3
+ padding: 0;
4
+ }
5
+
6
+ .repo {
7
+ display: block;
8
+ padding: 0 4px;
9
+ border-radius: 2px;
10
+
11
+ &:hover {
12
+ background: rgba(128, 212, 255, 0.1);
13
+ }
14
+
15
+ &.selected {
16
+ background: rgba(128, 212, 255, 0.25);
17
+ }
18
+
19
+ &.disabled {
20
+ background: #f9f9f9;
21
+ }
22
+
23
+ &.retired {
24
+ .repo-owner { color: #ddd; }
25
+ .repo-name > .label { opacity: 0.4; }
26
+ .repo-owner, .repo-name {
27
+ position: relative;
28
+
29
+ &::after {
30
+ display: block;
31
+ content: '.';
32
+ color: transparent;
33
+ position: absolute;
34
+ top: 0;
35
+ left: 0;
36
+ height: 50%;
37
+ width: 100%;
38
+ margin: 0;
39
+ border-bottom: 2px solid #555;
40
+ }
41
+ }
42
+ }
43
+
44
+ input[type="checkbox"] {
45
+ margin: 8px;
46
+ float: left;
47
+
48
+ &[disabled] + label {
49
+ color: #bbb;
50
+ }
51
+ }
52
+
53
+ label {
54
+ padding: 4px 0;
55
+ margin: 0;
56
+ }
57
+
58
+ .repo-visibility {
59
+ display: inline-block;
60
+ margin: 0 4px;
61
+
62
+ .fa { width: 14px; }
63
+ .fa-unlock { opacity: 0.1; }
64
+ }
65
+
66
+ .repo-owner {
67
+ &::after {
68
+ display: inline-block;
69
+ content: '/';
70
+ margin: 0 0.33em;
71
+ }
72
+ }
73
+
74
+ .repo-name b {
75
+ color: #505050;
76
+ }
77
+ }
@@ -22,6 +22,8 @@ $project-navbar-height: 30px;
22
22
 
23
23
  .navbar .brand {
24
24
  padding: 6px 20px 10px;
25
+ position: relative;
26
+ z-index: 1;
25
27
  }
26
28
 
27
29
  // Don't let the navbar wrap onto multiple lines
@@ -1,68 +1,54 @@
1
- h4.github-repo {
2
- margin: 1.33em 0 0.66em;
3
- font-weight: 500;
1
+ td.pull-request-avatar {
2
+ width: 32px;
4
3
 
5
- .pull-requests-count { vertical-align: middle; }
6
- }
7
-
8
- ul.pull-requests { margin: 0; }
9
-
10
- .pull-request {
11
- list-style-type: none;
12
- display: block;
13
- margin: 0;
14
- line-height: 24px;
15
-
16
- &.back-burner a {
17
- color: #c9c9c9;
18
-
19
- .pull-request-author { opacity: 0.16; }
20
- .pull-request-number { color: #d6d6d6; }
21
- .pull-request-age { color: #d6d6d6; }
22
- }
23
-
24
- a {
25
- display: block;
26
- padding: 0.33em 0;
27
-
28
- &:hover {
29
- text-decoration: none;
30
- background: #EDF9FF;
31
- color: #005580;
32
-
33
- .pull-request-author { opacity: 1.0; }
34
- .pull-request-number { color: #6C8592; }
35
- .pull-request-age { color: #AABCC5; }
36
- }
4
+ img {
5
+ width: 32px;
6
+ height: 32px;
37
7
  }
38
8
  }
39
9
 
40
- .pull-request-number {
41
- display: inline-block;
42
- vertical-align: middle;
43
- text-align: right;
44
- width: 2.5em; // enough room for 4 digits (i.e. 9999 pull requests)
45
- font-size: 1.66em;
46
- font-weight: 100;
47
- color: #777;
48
- }
49
-
50
- .pull-request-author {
51
- vertical-align: middle;
52
- margin-left: 0.25em;
53
- width: 24px;
54
- height: 24px;
10
+ td.pull-request-project {
11
+ white-space: nowrap;
55
12
  }
56
13
 
57
- .pull-request-title {
14
+ .pull-request-labels .label {
58
15
  display: inline-block;
59
- vertical-align: middle;
60
- margin-left: 0.25em;
16
+ padding: 2px 4px 4px;
17
+ font-size: 11px;
18
+ font-weight: bold;
19
+ line-height: 1;
20
+ color: #fff;
21
+ border-radius: 2px;
22
+ box-shadow: inset 0 -1px 0 rgba(0,0,0,0.12);
61
23
  }
62
24
 
63
- .pull-request-age {
64
- display: inline-block;
65
- vertical-align: middle;
66
- margin-left: 0.5em;
67
- color: #c9c9c9;
25
+ .pull-request-labels-toggle {
26
+ margin: 0.66em 0 2em;
27
+
28
+ input[type="checkbox"] { visibility: hidden; width: 0; height: 0; }
29
+ label { display: inline-block; }
30
+
31
+ // Premailer does not like the selector. It will result in an error
32
+ // NoMethodError: undefined method `<<' for nil:NilClass
33
+ // hpricot-0.8.6/lib/hpricot/elements.rb:307→ filter
34
+ // hpricot-0.8.6/lib/hpricot/elements.rb:290→ filter
35
+ // hpricot-0.8.6/lib/hpricot/traverse.rb:327→ search
36
+ // premailer-1.8.6/lib/premailer/adapter/hpricot.rb:46→ block in to_inline_css
37
+ // css_parser-1.3.7/lib/css_parser/parser.rb:192→ block (2 levels) in each_selector
38
+ // css_parser-1.3.7/lib/css_parser/rule_set.rb:90→ block in each_selector
39
+ // css_parser-1.3.7/lib/css_parser/rule_set.rb:90→ each
40
+ // css_parser-1.3.7/lib/css_parser/rule_set.rb:90→ each_selector
41
+ // css_parser-1.3.7/lib/css_parser/parser.rb:191→ block in each_selector
42
+ // css_parser-1.3.7/lib/css_parser/parser.rb:180→ block in each_rule_set
43
+ // css_parser-1.3.7/lib/css_parser/parser.rb:178→ each
44
+ // css_parser-1.3.7/lib/css_parser/parser.rb:178→ each_rule_set
45
+ // css_parser-1.3.7/lib/css_parser/parser.rb:190→ each_selector
46
+ // premailer-1.8.6/lib/premailer/adapter/hpricot.rb:21→ to_inline_css
47
+ // houston-core-57242effb689/app/mailers/view_mailer.rb:65→ block (2 levels) in mail
48
+ input[type="checkbox"]:not(:checked) + label {
49
+ .label {
50
+ background: #efefef !important;
51
+ color: #888 !important;
52
+ }
53
+ }
68
54
  }
@@ -2,6 +2,11 @@
2
2
  border-radius: 100em;
3
3
  }
4
4
 
5
+ .avatar.avatar-not-our-user {
6
+ border: 2px dotted #aaa;
7
+ margin: -2px;
8
+ }
9
+
5
10
  // just like on the timeline page
6
11
  h1.project-banner .avatar {
7
12
  float: right;
@@ -1,12 +1,15 @@
1
+ $default: rgb(80,80,80);
1
2
  <% Houston.config.project_colors.each do |name, value| %>
2
3
  $<%= name %>: <%= value.rgb %>;
3
4
  <% end %>
4
5
 
6
+ <% project_colors = %w{default} + Houston.config.project_colors.keys %>
7
+
5
8
  .label {
6
9
  vertical-align: baseline;
7
10
  font-weight: 400;
8
11
 
9
- <% Houston.config.project_colors.each do |name, value| %>
12
+ <% project_colors.each do |name| %>
10
13
  &.<%= name %> { background-color: $<%= name %>; }
11
14
  <% end %>
12
15
 
@@ -17,7 +20,7 @@
17
20
  }
18
21
 
19
22
  .dashboard .label {
20
- <% Houston.config.project_colors.each do |name, value| %>
23
+ <% project_colors.each do |name| %>
21
24
  &.<%= name %> {
22
25
  background-color: $<%= name %>;
23
26
  color: rgba(255,255,255,0.9);
@@ -36,13 +39,13 @@
36
39
  top: 1px;
37
40
  margin-left: 0.25em;
38
41
 
39
- <% Houston.config.project_colors.each do |name, value| %>
42
+ <% project_colors.each do |name| %>
40
43
  &.<%= name %> { background-color: $<%= name %>; }
41
44
  <% end %>
42
45
  }
43
46
 
44
47
  .project-tile {
45
- <% Houston.config.project_colors.each do |name, value| %>
48
+ <% project_colors.each do |name| %>
46
49
  &.<%= name %>:hover { background-color: $<%= name %>; }
47
50
  <% end %>
48
51
  }
@@ -50,12 +53,12 @@
50
53
  #email_body h1.project-banner,
51
54
  .current-project,
52
55
  .project-navbar {
53
- <% Houston.config.project_colors.each do |name, value| %>
56
+ <% project_colors.each do |name| %>
54
57
  &.<%= name %> { background-color: $<%= name %>; }
55
58
  <% end %>
56
59
  }
57
60
 
58
- <% Houston.config.project_colors.each do |name, value| %>
61
+ <% project_colors.each do |name| %>
59
62
  .project-navbar.<%= name %> .nav > li.current,
60
63
  .project-banner.<%= name %> {
61
64
  background-color: lighten($<%= name %>, 32%);
@@ -72,7 +75,7 @@
72
75
 
73
76
  .modal-header { background-color: #73746F; }
74
77
 
75
- <% Houston.config.project_colors.each do |name, value| %>
78
+ <% project_colors.each do |name| %>
76
79
  #new_ticket_modal.<%= name %> {
77
80
  .modal-header { background-color: $<%= name %>; }
78
81
  }