houston-core 0.7.0.beta3 → 0.7.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +56 -56
  3. data/app/assets/javascripts/houston/app/infinite_scroll.coffee +6 -2
  4. data/app/assets/javascripts/houston/app/models/ticket.coffee +0 -42
  5. data/app/assets/javascripts/houston/app/ticket_tracker_refresh.coffee +0 -2
  6. data/app/assets/javascripts/houston/app/views/keyboard_shortcuts_modal.coffee +0 -6
  7. data/app/assets/javascripts/houston/core/handlebars_helpers.coffee +0 -5
  8. data/app/assets/stylesheets/houston/application/actions.scss +15 -0
  9. data/app/assets/stylesheets/houston/application/layout.scss +3 -0
  10. data/app/assets/stylesheets/houston/application/markdown.scss +1 -1
  11. data/app/assets/stylesheets/houston/application/navigation.scss +3 -1
  12. data/app/assets/stylesheets/houston/application/project_banner_buttons.scss +2 -0
  13. data/app/assets/stylesheets/houston/application/tables.scss +0 -1
  14. data/app/assets/stylesheets/houston/application/timeline.scss +1 -1
  15. data/app/assets/stylesheets/houston/core/overrides.scss +2 -1
  16. data/app/concerns/houston/props.rb +11 -4
  17. data/app/concerns/project_adapter.rb +1 -1
  18. data/app/concerns/unique_add.rb +1 -1
  19. data/app/controllers/actions_controller.rb +39 -0
  20. data/app/controllers/commits_controller.rb +1 -1
  21. data/app/controllers/errors_controller.rb +10 -0
  22. data/app/controllers/hooks_controller.rb +1 -1
  23. data/app/controllers/omnibar_controller.rb +1 -11
  24. data/app/controllers/project_hooks_controller.rb +2 -2
  25. data/app/controllers/projects_controller.rb +2 -0
  26. data/app/controllers/test_runs_controller.rb +14 -3
  27. data/app/controllers/triggers_controller.rb +8 -0
  28. data/app/helpers/actions_helper.rb +7 -0
  29. data/app/helpers/application_helper.rb +1 -1
  30. data/app/interactors/cache_key_dependencies.rb +1 -1
  31. data/app/interactors/test_run_comparer.rb +1 -1
  32. data/app/mailers/project_notification.rb +0 -31
  33. data/app/models/ability.rb +0 -11
  34. data/app/models/{job.rb → action.rb} +19 -7
  35. data/app/models/commit.rb +2 -2
  36. data/app/models/deploy.rb +3 -3
  37. data/app/models/github/comment_event.rb +9 -3
  38. data/app/models/github/post_receive_event.rb +1 -1
  39. data/app/models/github/pull_request.rb +5 -5
  40. data/app/models/persistent_trigger.rb +46 -0
  41. data/app/models/project.rb +0 -1
  42. data/app/models/release.rb +1 -1
  43. data/app/models/run_tests_on_post_receive.rb +17 -17
  44. data/app/models/task.rb +4 -4
  45. data/app/models/test_run.rb +18 -5
  46. data/app/models/ticket.rb +2 -21
  47. data/app/models/ticket_antecedent.rb +3 -3
  48. data/app/models/user.rb +0 -1
  49. data/app/views/actions/index.html.erb +69 -0
  50. data/app/views/actions/show.html.erb +45 -0
  51. data/app/views/commits/show.html.erb +7 -8
  52. data/app/views/errors/_actions.html.erb +11 -0
  53. data/app/views/errors/index.html.erb +39 -0
  54. data/app/views/layouts/_mobile_navigation.html.erb +1 -9
  55. data/app/views/layouts/_navigation.html.erb +14 -8
  56. data/app/views/layouts/application.html.erb +1 -3
  57. data/app/views/project_notification/test_run.html.erb +13 -3
  58. data/app/views/projects/_form.html.erb +13 -7
  59. data/app/views/triggers/index.html.erb +39 -0
  60. data/config/initializers/add_navigation_renderers.rb +0 -6
  61. data/config/initializers/houston_async.rb +4 -2
  62. data/config/initializers/houston_scheduler_daemon.rb +6 -0
  63. data/config/initializers/load_persistent_triggers.rb +7 -0
  64. data/config/initializers/requirements.rb +2 -1
  65. data/config/initializers/sync_commits_on_post_receive.rb +2 -2
  66. data/config/routes.rb +17 -15
  67. data/db/migrate/20160711170921_rename_jobs_to_actions.rb +5 -0
  68. data/db/migrate/20160713204605_add_trigger_and_params_to_actions.rb +6 -0
  69. data/db/migrate/20160715173039_create_persistent_triggers.rb +10 -0
  70. data/db/structure.sql +197 -221
  71. data/houston-core.gemspec +1 -1
  72. data/lib/houston/boot/actions.rb +105 -0
  73. data/lib/houston/boot/active_record_serializer.rb +24 -0
  74. data/lib/houston/boot/configuration.rb +118 -49
  75. data/lib/houston/boot/events.rb +46 -0
  76. data/lib/houston/boot/extensions.rb +118 -14
  77. data/lib/houston/boot/observer.rb +122 -24
  78. data/lib/houston/boot/readonly_hash_serializer.rb +15 -0
  79. data/lib/houston/boot/serializer.rb +83 -0
  80. data/lib/houston/boot/ticket_antecedent_serializer.rb +21 -0
  81. data/lib/houston/boot/timer.rb +45 -0
  82. data/lib/houston/boot/triggers.rb +75 -0
  83. data/lib/houston/boot.rb +5 -0
  84. data/lib/houston/version.rb +1 -1
  85. data/lib/params_serializer.rb +18 -0
  86. data/lib/tasks/actions.rake +12 -0
  87. data/lib/tasks/events.rake +11 -0
  88. data/templates/new-instance/config/abilities.rb +0 -8
  89. data/templates/new-instance/config/{triggers → events}/alerts/slack_when_assigned.rb +1 -1
  90. data/templates/new-instance/config/{triggers → events}/alerts/slack_when_opened.rb +1 -1
  91. data/templates/new-instance/config/{triggers → events}/daemons/health.rb +6 -6
  92. data/templates/new-instance/config/{triggers → events}/deploy/autoresolve_errs.rb +1 -1
  93. data/templates/new-instance/config/{triggers → events}/deploy/checkout_mentioned_alerts.rb +1 -1
  94. data/templates/new-instance/config/{triggers → events}/deploy/notify_deployer_when_finished.rb +2 -2
  95. data/templates/new-instance/config/{triggers → events}/github/publish_comments_on_slack.rb +9 -9
  96. data/templates/new-instance/config/{triggers → events}/tests/slack_when_analyzed.rb +1 -1
  97. data/templates/new-instance/config/{triggers → events}/tests/slack_when_completed.rb +1 -1
  98. data/templates/new-instance/config/{triggers → events}/tickets/mark_tasks_completed_on_commit.rb +1 -1
  99. data/templates/new-instance/config/main.rb +8 -35
  100. data/templates/new-instance/config/{jobs → timers}/cache_key_dependencies.rb +0 -0
  101. data/templates/new-instance/config/{jobs → timers}/email_about_open_alerts.rb +0 -0
  102. data/templates/new-instance/config/{jobs → timers}/purge_jobs.rb +0 -0
  103. data/templates/new-instance/config/{jobs → timers}/slack_reminders_about_alerts.rb +0 -0
  104. data/templates/new-instance/config/{jobs → timers}/sync_commits.rb +0 -0
  105. data/templates/new-instance/config/{jobs → timers}/sync_pull_requests.rb +0 -0
  106. data/templates/new-instance/config/{jobs → timers}/sync_tickets.rb +0 -0
  107. data/templates/new-module/lib/houston/%name%.rb +13 -0
  108. data/test/integration/ci_integration_test.rb +5 -5
  109. data/test/integration/web_hook_test.rb +1 -1
  110. data/test/test_helper.rb +14 -0
  111. data/test/unit/controllers/hooks_controller_test.rb +2 -2
  112. data/test/unit/initializers/sync_commits_on_post_receive_test.rb +1 -1
  113. data/test/unit/models/actions_test.rb +107 -0
  114. data/test/unit/models/configuration_test.rb +108 -0
  115. data/test/unit/models/observer_test.rb +87 -3
  116. data/test/unit/models/persistent_trigger_test.rb +94 -0
  117. data/test/unit/models/serializer_test.rb +80 -0
  118. data/test/unit/models/triggers_test.rb +53 -0
  119. metadata +60 -60
  120. data/app/assets/javascripts/houston/app/models/testing_note.coffee +0 -18
  121. data/app/assets/javascripts/houston/app/views/commit_view.coffee +0 -13
  122. data/app/assets/javascripts/houston/app/views/testing_note_view.coffee +0 -85
  123. data/app/assets/javascripts/houston/app/views/testing_report_view.coffee +0 -29
  124. data/app/assets/javascripts/houston/app/views/testing_ticket_view.coffee +0 -203
  125. data/app/assets/stylesheets/houston/application/jobs.scss +0 -5
  126. data/app/assets/stylesheets/houston/application/testing_report.scss +0 -279
  127. data/app/assets/templates/commit.hbs +0 -9
  128. data/app/assets/templates/testing_notes/edit.hbs +0 -20
  129. data/app/assets/templates/testing_notes/new.hbs +0 -27
  130. data/app/assets/templates/testing_notes/show.hbs +0 -11
  131. data/app/assets/templates/testing_report/description.hbs +0 -12
  132. data/app/assets/templates/testing_report/ticket.hbs +0 -21
  133. data/app/assets/templates/testing_report/verdict.hbs +0 -4
  134. data/app/controllers/jobs_controller.rb +0 -42
  135. data/app/controllers/testing_notes_controller.rb +0 -50
  136. data/app/controllers/testing_report_controller.rb +0 -38
  137. data/app/models/testing_note.rb +0 -64
  138. data/app/presenters/testing_note_presenter.rb +0 -27
  139. data/app/presenters/testing_report_ticket_presenter.rb +0 -71
  140. data/app/views/jobs/index.html.erb +0 -72
  141. data/app/views/jobs/show.html.erb +0 -41
  142. data/app/views/project_notification/testing_note.html.erb +0 -9
  143. data/app/views/testing_report/_scripts.html.erb +0 -12
  144. data/app/views/testing_report/index.html.erb +0 -31
  145. data/app/views/testing_report/show.html.erb +0 -29
  146. data/config/initializers/houston_scheduler.rb +0 -23
  147. data/db/migrate/20120424212706_create_testing_notes.rb +0 -14
  148. data/db/migrate/20120501231817_add_expires_at_to_testing_notes.rb +0 -5
  149. data/db/migrate/20120501231948_add_unfuddle_id_to_testing_notes.rb +0 -5
  150. data/db/migrate/20120715230526_change_testing_notes_comment_to_text.rb +0 -9
  151. data/db/migrate/20130211015046_add_min_passing_verdicts_to_projects.rb +0 -5
  152. data/db/migrate/20130407220039_add_project_id_to_testing_notes.rb +0 -26
  153. data/db/migrate/20140511024021_rename_testing_notes_unfuddle_id_to_remote_id.rb +0 -5
  154. data/templates/new-instance/config/triggers/tickets/email_testing_notes.rb +0 -7
  155. data/templates/new-instance/log/development.log +0 -41253
  156. data/templates/new-instance/log/test.log +0 -545
  157. data/templates/new-module/config/initializers/add_navigation_renderer.rb +0 -3
@@ -1,203 +0,0 @@
1
- class window.TestingTicketView extends Backbone.View
2
- tagName: 'tr'
3
- className: 'ticket'
4
-
5
- events:
6
- 'click .close-button': 'closeTicket'
7
- 'click .reopen-button': 'reopenTicket'
8
- 'click a.ticket-set-priority': 'setPriority'
9
-
10
- initialize: ->
11
- @ticket = @options.ticket
12
- @canClose = @options.canClose
13
- @testingNotes = @ticket.testingNotes()
14
-
15
- @renderTicket = HandlebarsTemplates['testing_report/ticket']
16
- @renderTicketDescription = HandlebarsTemplates['testing_report/description']
17
- @renderTesterVerdict = HandlebarsTemplates['testing_report/verdict']
18
- @renderNewTestingNote = HandlebarsTemplates['testing_notes/new']
19
- Handlebars.registerPartial 'testerVerdict', @renderTesterVerdict
20
-
21
- @numColumns = window.testers.length + 1
22
- @viewInEdit = null
23
-
24
- render: ->
25
- ticket = @ticket.toJSON()
26
- # window.console.log "[ticket] render ##{ticket.number}", ticket
27
-
28
- $el = $(@el)
29
- $el.attr 'id', "ticket_#{@ticket.id}"
30
- ticket.canClose = @canClose
31
- ticket.testerVerdicts = @ticket.testerVerdicts()
32
- ticket.verdict = @ticket.verdict()
33
- ticket.passing = ticket.verdict == 'Passing'
34
- ticket.failing = ticket.verdict == 'Failing'
35
- $el.html @renderTicket(ticket)
36
-
37
- $el.addClass("ticket-priority-#{ticket.priority}")
38
- $el.toggleClass('failing', ticket.failing)
39
- $el.toggleClass('passing', ticket.passing)
40
- $el.find('.close-button').toggleClass('btn-success', ticket.passing)
41
- @
42
-
43
- renderExpandedRow: ->
44
- @$testingNotes = @renderTestingNotes()
45
-
46
- renderTestingNotes: ->
47
- id = "ticket_#{@ticket.get('id')}_testing_notes"
48
- ticket = @ticket.toJSON()
49
- ticket.colspan = @numColumns
50
- $tr = $ @renderTicketDescription(ticket)
51
-
52
- @$el.after $tr
53
-
54
- $testingNotes = $tr.find('ol.testing-notes')
55
-
56
- @ticket.activityStream().each (item)=>
57
- if item.constructor == TestingNote
58
- $testingNotes.appendView @viewForTestingNote(item)
59
- else if item.constructor == Commit
60
- $testingNotes.appendView @viewForCommit(item)
61
-
62
- # Render form for adding a testing note
63
- if window.userId
64
- params =
65
- projectSlug: @ticket.get('projectSlug')
66
- ticketId: @ticket.get('id')
67
- tester: window.user.get('role') == 'Tester'
68
- developer: window.user.get('role') == 'Developer'
69
- $testingNotes.append @renderNewTestingNote(params)
70
-
71
- $tr.find('form#new_testing_note').submit _.bind(@createTestingNote, @)
72
- $tr.find('form#new_testing_note :radio[name="verdict"]').click =>
73
- verdict = $tr.find('form#new_testing_note :radio[name="verdict"]:checked').val() || 'none'
74
- $tr.find('.testing-note.new').attr('class', "testing-note new by-tester #{verdict}")
75
-
76
- $tr.find('.btn-post-and-reset').click _.bind(@createTestingNoteAndResetTicket, @)
77
-
78
- $testingNotes
79
-
80
- beginEditTestingNote: (view)->
81
- window.console.log('beginEditTestingNote', view, @viewInEdit, @)
82
- @viewInEdit.commit() if @viewInEdit && @viewInEdit != view
83
- @viewInEdit = view
84
-
85
- cancelEditTestingNote: ->
86
- @viewInEdit = null
87
-
88
- commitEditTestingNote: (view, testingNote)->
89
- @viewInEdit = null
90
- @renderTesterVerdicts()
91
- @trigger('testing_note:refresh')
92
-
93
- destroyTestingNote: (view, testingNote)->
94
- @testingNotes.remove(testingNote)
95
- $(view.el).remove()
96
- @renderTesterVerdicts()
97
-
98
- viewForTestingNote: (testingNote)->
99
- view = new TestingNoteView(model: testingNote)
100
- view.on 'edit:begin', _.bind(@beginEditTestingNote, @)
101
- view.on 'edit:cancel', _.bind(@cancelEditTestingNote, @)
102
- view.on 'edit:commit', _.bind(@commitEditTestingNote, @)
103
- view.on 'destroy', _.bind(@destroyTestingNote, @)
104
- view
105
-
106
- viewForCommit: (commit)->
107
- new CommitView(model: commit)
108
-
109
- addTestingNote: (testingNote)->
110
- @testingNotes.add(testingNote)
111
-
112
- return unless @$testingNotes
113
- view = @viewForTestingNote(testingNote)
114
- view.render()
115
- $(view.el).insertBefore(@$testingNotes.find('.testing-note.new')).highlight()
116
- @renderTesterVerdicts()
117
-
118
- renderTesterVerdicts: ->
119
- @render()
120
-
121
- createTestingNote: (e)->
122
- e.preventDefault()
123
- $form = $(e.target).closest('form')
124
- params = $form.serializeObject()
125
- testingNote = new TestingNote
126
- ticketId: @ticket.get('id')
127
-
128
- $form.disable()
129
-
130
- testingNote.save params,
131
- success: (model, response)=>
132
- $('.alert').remove()
133
- $form.closest('.testing-note.new').attr('class', 'testing-note new by-tester')
134
- $form.reset()
135
- @addTestingNote(testingNote)
136
- @trigger('testing_note:refresh')
137
- error: (model, response)=>
138
- errors = Errors.fromResponse(response)
139
- if errors.missingCredentials or errors.invalidCredentials
140
- App.promptForCredentialsTo('Unfuddle')
141
- errors.renderToAlert()
142
- complete: ->
143
- $form.enable()
144
-
145
- createTestingNoteAndResetTicket: (e)->
146
- params = {lastReleaseAt: new Date()}
147
- @ticket.save params,
148
- success: (model, response)=>
149
- console.log('updated lastReleaseAt', arguments)
150
- @render()
151
- error: (model, response)=>
152
- console.log('failed to update lastReleaseAt', arguments)
153
-
154
- @createTestingNote(e)
155
-
156
- closeTicket: (e)->
157
- e.preventDefault()
158
- $btn = $(e.target)
159
-
160
- @collapse()
161
-
162
- if $btn.hasClass('btn-success') || confirm('Are you suuuure? The ticket\'s not passing...')
163
- @$el.addClass('deleting')
164
- @$el.find('button').attr('disabled', 'disabled')
165
-
166
- @ticket.destroy
167
- url: "/tickets/#{@ticket.id}/close"
168
- wait: true
169
- success: (model, response)=>
170
- @remove()
171
- error: (model, response)=>
172
- @$el.removeClass('deleting')
173
- @$el.find('button').removeAttr('disabled')
174
- App.showErrorMessage("Unable to close ticket", response.responseText)
175
-
176
- reopenTicket: (e)->
177
- e.preventDefault()
178
- $btn = $(e.target)
179
-
180
- @collapse()
181
-
182
- if confirm('Are you sure you want to REOPEN this ticket?')
183
- @$el.addClass('deleting')
184
- @$el.find('button').attr('disabled', 'disabled')
185
- @ticket.destroy
186
- url: "/tickets/#{@ticket.id}/reopen"
187
- wait: true
188
- success: (model, response)=>
189
- @remove()
190
- error: (model, response)=>
191
- @$el.removeClass('deleting')
192
- @$el.find('button').removeAttr('disabled')
193
- App.showErrorMessage("Unable to close ticket", response.responseText)
194
-
195
-
196
-
197
- setPriority: (e)->
198
- $a = $(e.target)
199
- priority = $a.data('priority')
200
- priority = 'normal' if @$el.hasClass("ticket-priority-#{priority}")
201
- @$el.removeClass 'ticket-priority-low ticket-priority-normal ticket-priority-high'
202
- @$el.addClass "ticket-priority-#{priority}"
203
- @ticket.save priority: priority
@@ -1,5 +0,0 @@
1
- .scheduler-job-success-rate {
2
- font-size: 0.75em;
3
- line-height: 20px;
4
- float: right;
5
- }
@@ -1,279 +0,0 @@
1
-
2
- .nomargin { margin: 0 -20px; }
3
-
4
- #testing_report {
5
- .avatar { border-radius: 0; }
6
- }
7
-
8
- .testing-report-table {
9
- margin-bottom: 4em;
10
-
11
- th {
12
- font-weight: bold;
13
- text-align: left;
14
- height: 7.5em;
15
-
16
- &.ticket-participants {
17
- padding: 0 0 8px 0;
18
-
19
- &::after {
20
- display: inline-block;
21
- width: 28px;
22
- text-align: center;
23
- }
24
- }
25
- }
26
-
27
- td { vertical-align: top; }
28
-
29
- tbody {
30
- tr.passing td {
31
- background-color: rgba(26, 223, 18, 0.18);
32
- color: rgb(70, 156, 44);
33
- color: rgba(70, 156, 44, 0.66);
34
-
35
- &.ticket-due-date { text-decoration: line-through; }
36
- .label-inverse { background-color: rgb(70, 156, 44); }
37
- }
38
- tr.failing td {
39
- background-color: rgba(223, 92, 18, 0.18);
40
-
41
- &.ticket-summary { color: #B50000; }
42
- .label-inverse { background-color: #B50000; }
43
- }
44
- tr.expanded td {
45
- &.ticket-due-date { text-decoration: none; }
46
- }
47
- tr.deleting { opacity: 0.2 !important; }
48
- }
49
-
50
- .ticket-project { white-space: nowrap; font-weight: bold; }
51
- .ticket-due-date { white-space: nowrap; }
52
- td.ticket-due-date { color: #B50000; font-size: 0.8333em; }
53
- .ticket-participants {
54
- width: 28px;
55
- max-width: 28px;
56
- padding: 4px 0;
57
-
58
- &.current-tester { font-weight: bold; }
59
- }
60
- }
61
-
62
- .tester-verdicts { overflow: hidden; }
63
-
64
- .tester-avatar,
65
- .committer-avatar {
66
- display: block;
67
- margin: 1px;
68
-
69
- img {
70
- background-color: white;
71
- border: 2px solid black;
72
- }
73
- }
74
-
75
- .ticket-verdict {
76
- display: block;
77
- margin: 1px;
78
-
79
- img {
80
- background-color: white;
81
- margin: 2px;
82
- opacity: 0.15;
83
- }
84
-
85
- &.current-tester img { opacity: 0.60; }
86
-
87
- &[data-verdict="passing"] img { opacity: 1.0; margin: 0; border: solid 2px #55c832; }
88
- &[data-verdict="comment"] img { opacity: 1.0; margin: 0; border: solid 2px #777777; }
89
- &[data-verdict="badticket"] img { opacity: 1.0; margin: 0; border: solid 2px #FFF51D; }
90
- &[data-verdict="failing"] img { opacity: 1.0; margin: 0; border: solid 2px #ff3030; }
91
- }
92
-
93
- .testing-notes {
94
- display: block;
95
- max-width: 600px;
96
- margin-bottom: 2em;
97
-
98
- &.collapse { display: none; }
99
-
100
- .commit, .testing-note, .ticket-description {
101
- display: block;
102
- position: relative;
103
- padding: 15px;
104
- -webkit-border-radius: 10px;
105
- -moz-border-radius: 10px;
106
- border-radius: 10px;
107
- border-width: 2px;
108
- border-style: solid;
109
- clear: both;
110
-
111
- .testing-note-timestamp { line-height: 1em; color: #333; display: block; font-size: 0.88em; }
112
- }
113
-
114
- .ticket-description {
115
- background: #e9e9e9;
116
- border-color: #777777;
117
- margin: 0.5em 0;
118
- word-wrap: break-word;
119
- color: #333;
120
-
121
- hr { border-top-color: #ccc; }
122
- }
123
-
124
- .commit, .testing-note {
125
- margin: 0.5em 60px 0.5em 40px;
126
-
127
- .tester-avatar,
128
- .committer-avatar {
129
- float: left;
130
- position: relative;
131
- left: -57px;
132
- margin-right: -40px;
133
- background-color: white;
134
- }
135
-
136
- &::before {
137
- content: '';
138
- position: absolute;
139
- border-style: solid;
140
- display: block;
141
- width: 0;
142
-
143
- top: 19px;
144
- bottom: auto;
145
- border-top-color: transparent;
146
- border-bottom-color: transparent;
147
-
148
- left: -12px;
149
- right: auto;
150
- border-width: 8px 12px 8px 0;
151
- }
152
-
153
- &::after {
154
- content: '';
155
- position: absolute;
156
- border-style: solid;
157
- display: block;
158
- width: 0;
159
-
160
- top: 21px;
161
- bottom: auto;
162
- border-top-color: transparent;
163
- border-bottom-color: transparent;
164
-
165
- left: -7px;
166
- right: auto;
167
- border-width: 6px 9px 6px 0;
168
- }
169
- }
170
-
171
- .commit {
172
- background: #e9e9e9;
173
- border-color: #222;
174
-
175
- &::before {
176
- border-left-color: #222;
177
- border-right-color: #222;
178
- }
179
-
180
- &::after {
181
- border-left-color: #e9e9e9;
182
- border-right-color: #e9e9e9;
183
- }
184
- }
185
-
186
- .testing-note {
187
- background-color: white;
188
-
189
- &::after {
190
- border-left-color: white;
191
- border-right-color: white;
192
- }
193
-
194
- &.by-tester {
195
- margin: 0.5em 40px 0.5em 60px;
196
-
197
- &::before {
198
- left: auto;
199
- right: -12px;
200
- border-width: 8px 0 8px 12px;
201
- }
202
-
203
- &::after {
204
- left: auto;
205
- right: -7px;
206
- border-width: 6px 0 6px 9px;
207
- border-color: transparent white;
208
- }
209
-
210
- .tester-avatar {
211
- float: right;
212
- position: relative;
213
- left: 60px;
214
- margin-right: auto;
215
- background-color: white;
216
- }
217
- }
218
-
219
- textarea {
220
- width: 80%;
221
- height: 80px;
222
- }
223
-
224
- &.works { img { border-color: #0a0; } color: #0a0; }
225
- &.fails { img { border-color: #c11; } color: #c11; }
226
- &.badticket { img { border-color: #F5ED28; } color: #F5ED28; .tester-comment, form { color: #333; } }
227
- &.none { img { border-color: #777777; } color: #777777; }
228
- }
229
- }
230
-
231
-
232
- .testing-note {
233
-
234
- // no style when verdict is 'none'
235
- }
236
-
237
- .testing-note-form {
238
- margin-bottom: 0;
239
- label {
240
- display: inline-block;
241
-
242
- input {
243
- display: inline;
244
- margin: 0;
245
- }
246
- }
247
- p { margin: 0; }
248
- }
249
-
250
- .reopen-button { color: #888; }
251
- .close-button { color: #888; &.btn-success { color: white; } }
252
-
253
- .table td.ticket-testingPriority {
254
- padding: 0;
255
- .fa-arrow-up { padding: 12px 2px 12px 8px; display: inline-block; }
256
- .fa-arrow-down { padding: 12px 8px 12px 2px; display: inline-block; }
257
- }
258
-
259
- .table thead td {
260
- vertical-align: bottom;
261
- border-bottom: 4px solid transparent;
262
- }
263
-
264
- td.ticket-testingPriority { white-space: nowrap; }
265
-
266
-
267
- .ticket-priority-low .ticket-testingPriority .fa-arrow-down { color: #239ce7 !important; }
268
- .ticket-priority-high .ticket-testingPriority .fa-arrow-up { color: #e74c23 !important; }
269
- thead .ticket-testingPriority { color: #ccc; }
270
- tbody .ticket-testingPriority {
271
- i, a { color: rgba(0, 0, 0, 0.04); }
272
- a:hover {
273
- text-decoration: none;
274
- cursor: pointer;
275
-
276
- &.fa-arrow-down { color: rgba(35, 156, 231, 0.6); }
277
- &.fa-arrow-up { color: rgba(231, 76, 35, 0.6); }
278
- }
279
- }
@@ -1,9 +0,0 @@
1
- <span class="committer-avatar">{{{avatar committer/email 24 committer/name}}}</span>
2
- <div class="testing-note-body">
3
- <span class="testing-note-timestamp">
4
- {{formatTime createdAt}}&nbsp;&nbsp;
5
- {{{linkToCommit this}}}&nbsp;&nbsp;
6
- Updated in <b>{{environment}}</b>
7
- </span>
8
- <span class="tester-comment">{{{markdown message}}}</span>
9
- </div>
@@ -1,20 +0,0 @@
1
- <div class="tester-avatar">{{{avatarImage}}}</div>
2
- <form accept-charset="UTF-8" action="/tickets/{{ticketId}}/testing_notes/{{id}}" class="testing-note-form" id="edit_testing_note_{{id}}" method="post">
3
- <p>
4
- <input data-attr="ticket_id" id="testing_note_{{id}}_ticket_id" name="ticket_id" type="hidden" value="{{ticketId}}" />
5
- {{#if tester}}
6
- <label for="testing_note_{{id}}_verdict_works">{{{radioButton "testing_note" id "verdict" "works" verdict}}} Works as written</label> (Could be improved?
7
- <a href="/projects/{{projectSlug}}/tickets/new" target="_blank">File a ticket!</a> <img alt="stuck_out_tongue_winking_eye" height="20" width="20" src="/images/emoji/stuck_out_tongue_winking_eye.png" class="emoji">)<br />
8
- <label for="testing_note_{{id}}_verdict_fails">{{{radioButton "testing_note" id "verdict" "fails" verdict}}} Doesn't do what it says or introduces a regression</label><br />
9
- <label for="testing_note_{{id}}_verdict_badticket">{{{radioButton "testing_note" id "verdict" "badticket" verdict}}} I do not understand how to test this ticket</label><br />
10
- <label for="testing_note_{{id}}_verdict_none">{{{radioButton "testing_note" id "verdict" "none" verdict}}} No verdict</label>
11
- {{/if}}
12
- </p>
13
- <p>
14
- <textarea id="testing_note_comment" name="comment">{{comment}}</textarea>
15
- </p>
16
- <p>
17
- <button class="btn btn-primary" name="commit" type="submit">Save</button>
18
- <button class="btn btn-cancel" name="cancel">Cancel</button>
19
- </p>
20
- </form>
@@ -1,27 +0,0 @@
1
- <li class="testing-note{{#if tester}} by-tester{{/if}} new">
2
- <div class="tester-avatar">{{{userAvatar 24}}}</div>
3
- <form accept-charset="UTF-8" action="/tickets/{{ticketId}}/testing_notes" class="testing-note-form" id="new_testing_note" method="post">
4
- {{#if tester}}
5
- <p>
6
- <input data-attr="ticket_id" id="ticket_{{ticketId}}_new_testing_note_ticket_id" name="ticket_id" type="hidden" value="{{ticketId}}" />
7
- <label for="ticket_{{ticketId}}_new_testing_note_verdict_works"><input id="ticket_{{ticketId}}_new_testing_note_verdict_works" name="verdict" type="radio" value="works"> Works as written</label> (Could be improved?
8
- <a href="/projects/{{projectSlug}}/tickets/new" target="_blank">File a ticket!</a> <img alt="stuck_out_tongue_winking_eye" height="20" width="20" src="/images/emoji/stuck_out_tongue_winking_eye.png" class="emoji">)<br />
9
- <label for="ticket_{{ticketId}}_new_testing_note_verdict_fails"><input id="ticket_{{ticketId}}_new_testing_note_verdict_fails" name="verdict" type="radio" value="fails"> Doesn't do what it says or introduces a regression</label><br />
10
- <label for="ticket_{{ticketId}}_new_testing_note_verdict_badticket"><input id="ticket_{{ticketId}}_new_testing_note_verdict_badticket" name="verdict" type="radio" value="badticket"> I do not understand how to test this ticket</label><br />
11
- <label for="ticket_{{ticketId}}_new_testing_note_verdict_none"><input id="ticket_{{ticketId}}_new_testing_note_verdict_none" name="verdict" type="radio" value="none"> No verdict</label>
12
- </p>
13
- {{else}}
14
- <input data-attr="ticket_id" id="ticket_{{ticketId}}_new_testing_note_ticket_id" name="ticket_id" type="hidden" value="{{ticketId}}" />
15
- <input data-attr="ticket_id" id="ticket_{{ticketId}}_new_testing_note_verdict" name="verdict" type="hidden" value="none" />
16
- {{/if}}
17
- <p>
18
- <textarea id="testing_note_comment" name="comment" value=""></textarea>
19
- </p>
20
- <p>
21
- <input class="btn btn-primary btn-post" name="commit" type="submit" value="Post" />
22
- {{#if developer}}
23
- <button class="btn btn-post-and-reset" id="commit_and_reset">Post Comment and Reset Verdict</button>
24
- {{/if}}
25
- </p>
26
- </form>
27
- </li>
@@ -1,11 +0,0 @@
1
- <div class="tester-avatar">{{{avatarImage}}}</div>
2
- <div class="testing-note-body">
3
- <span class="testing-note-timestamp">{{formatTime createdAt}}</span>
4
- <span class="tester-comment">{{{markdown comment}}}</span>
5
- {{#if editable}}
6
- <span class="tester-controls">
7
- <a href="#" class="edit-note">Edit</a>
8
- <a href="#" class="destroy-note">Delete</a>
9
- </span>
10
- {{/if}}
11
- </div>
@@ -1,12 +0,0 @@
1
- <tr class="expansion ticket-testing-notes">
2
- <td class="table-margin"></td>
3
- <td colspan="5">
4
- <ol id="ticket_{{id}}_testing_notes" class="testing-notes" style="display: none;">
5
- {{#if description}}
6
- <li class='ticket-description'>{{{description}}}</li>
7
- {{/if}}
8
- </ol>
9
- </td>
10
- <td class="white-space" colspan="{{colspan}}"></td>
11
- <td class="table-margin"></td>
12
- </tr>
@@ -1,21 +0,0 @@
1
- <td class="table-margin"></td>
2
- <td class="ticket-testingPriority">{{#if canClose}}<a class="ticket-set-priority fa-arrow-up" data-priority="high"></a><a class="ticket-set-priority fa-arrow-down" data-priority="low"></a>{{else}}<i class="fa fa-arrow-up"></i><i class="fa fa-arrow-down"></i>{{/if}}</td>
3
- <td class="ticket-project"><b class="bubble {{projectColor}}"></b> {{projectTitle}}</td>
4
- <td class="ticket-summary">
5
- {{{formatTicketSummary summary}}}
6
- <a href="{{ticketUrl}}" target="_blank" rel="tooltip" data-tooltip-placement="right" data-original-title="View in {{ticketSystem}}">[#{{number}}]</a>
7
- {{#if canClose}}
8
- <button class="reopen-button btn btn-mini">Reopen</button>
9
- <button class="close-button btn btn-mini">Close</button>
10
- {{/if}}
11
- </td>
12
- <td class="ticket-deployment">{{#if deployment}}<span class="label label-inverse">{{deployment}}</span>{{/if}}</td>
13
- <td class="ticket-due-date">{{#if dueDate}}
14
- <span class="hidden-text">{{dueDate}}</span>
15
- <span class="ticket-due-date">{{formatDate dueDate}}</span>
16
- {{/if}}</td>
17
- <td class="ticket-participants">{{#committers}} <span class="committer-avatar">{{{avatar email 24 name}}}</span>{{/committers}}</td>
18
- {{#testerVerdicts}}
19
- <td class="ticket-participants">{{> testerVerdict}}</td>
20
- {{/testerVerdicts}}
21
- <td class="table-margin"></td>
@@ -1,4 +0,0 @@
1
- <span class="ticket-verdict" data-verdict="{{verdict}}" data-tester-id="{{testerId}}">
2
- <span class="hidden-text">{{verdict}}</span>
3
- {{{testerAvatar email 24}}}
4
- </span>
@@ -1,42 +0,0 @@
1
- class JobsController < ApplicationController
2
-
3
- def index
4
- authorize! :show, :jobs
5
- jobs_by_name = $scheduler.jobs.each_with_object({}) { |job, map|
6
- map[job.tags.first] = {
7
- name: job.tags.first,
8
- schedule: job.original } }
9
-
10
- jobs = Job.where(name: jobs_by_name.keys)
11
-
12
- most_recent_jobs = jobs.joins(<<-SQL)
13
- inner join (select name, max(started_at) "started_at" from jobs group by name) "most_recent"
14
- on jobs.name=most_recent.name and jobs.started_at=most_recent.started_at
15
- SQL
16
- most_recent_jobs.each do |job|
17
- jobs_by_name[job.name][:last] = job
18
- end
19
-
20
- jobs.group(:name).unscope(:order).pluck(:name, "COUNT(id)", "COUNT(CASE WHEN succeeded THEN 1 ELSE NULL END)", "AVG(EXTRACT(epoch from finished_at - started_at))").each do |name, runs, successful_runs, avg_duration|
21
- jobs_by_name[name].merge!(
22
- runs: runs,
23
- successful_runs: successful_runs,
24
- avg_duration: avg_duration )
25
- end
26
-
27
- @jobs = jobs_by_name.values
28
- end
29
-
30
- def show
31
- authorize! :show, :jobs
32
- @job_name = params[:slug]
33
- @jobs = Job.where(name: @job_name).preload(:error)
34
- end
35
-
36
- def run
37
- authorize! :run, :jobs
38
- Houston.jobs.run params[:slug]
39
- redirect_to "/jobs", notice: "#{params[:slug]} is running"
40
- end
41
-
42
- end