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.
- checksums.yaml +4 -4
- data/Gemfile.lock +56 -56
- data/app/assets/javascripts/houston/app/infinite_scroll.coffee +6 -2
- data/app/assets/javascripts/houston/app/models/ticket.coffee +0 -42
- data/app/assets/javascripts/houston/app/ticket_tracker_refresh.coffee +0 -2
- data/app/assets/javascripts/houston/app/views/keyboard_shortcuts_modal.coffee +0 -6
- data/app/assets/javascripts/houston/core/handlebars_helpers.coffee +0 -5
- data/app/assets/stylesheets/houston/application/actions.scss +15 -0
- data/app/assets/stylesheets/houston/application/layout.scss +3 -0
- data/app/assets/stylesheets/houston/application/markdown.scss +1 -1
- data/app/assets/stylesheets/houston/application/navigation.scss +3 -1
- data/app/assets/stylesheets/houston/application/project_banner_buttons.scss +2 -0
- data/app/assets/stylesheets/houston/application/tables.scss +0 -1
- data/app/assets/stylesheets/houston/application/timeline.scss +1 -1
- data/app/assets/stylesheets/houston/core/overrides.scss +2 -1
- data/app/concerns/houston/props.rb +11 -4
- data/app/concerns/project_adapter.rb +1 -1
- data/app/concerns/unique_add.rb +1 -1
- data/app/controllers/actions_controller.rb +39 -0
- data/app/controllers/commits_controller.rb +1 -1
- data/app/controllers/errors_controller.rb +10 -0
- data/app/controllers/hooks_controller.rb +1 -1
- data/app/controllers/omnibar_controller.rb +1 -11
- data/app/controllers/project_hooks_controller.rb +2 -2
- data/app/controllers/projects_controller.rb +2 -0
- data/app/controllers/test_runs_controller.rb +14 -3
- data/app/controllers/triggers_controller.rb +8 -0
- data/app/helpers/actions_helper.rb +7 -0
- data/app/helpers/application_helper.rb +1 -1
- data/app/interactors/cache_key_dependencies.rb +1 -1
- data/app/interactors/test_run_comparer.rb +1 -1
- data/app/mailers/project_notification.rb +0 -31
- data/app/models/ability.rb +0 -11
- data/app/models/{job.rb → action.rb} +19 -7
- data/app/models/commit.rb +2 -2
- data/app/models/deploy.rb +3 -3
- data/app/models/github/comment_event.rb +9 -3
- data/app/models/github/post_receive_event.rb +1 -1
- data/app/models/github/pull_request.rb +5 -5
- data/app/models/persistent_trigger.rb +46 -0
- data/app/models/project.rb +0 -1
- data/app/models/release.rb +1 -1
- data/app/models/run_tests_on_post_receive.rb +17 -17
- data/app/models/task.rb +4 -4
- data/app/models/test_run.rb +18 -5
- data/app/models/ticket.rb +2 -21
- data/app/models/ticket_antecedent.rb +3 -3
- data/app/models/user.rb +0 -1
- data/app/views/actions/index.html.erb +69 -0
- data/app/views/actions/show.html.erb +45 -0
- data/app/views/commits/show.html.erb +7 -8
- data/app/views/errors/_actions.html.erb +11 -0
- data/app/views/errors/index.html.erb +39 -0
- data/app/views/layouts/_mobile_navigation.html.erb +1 -9
- data/app/views/layouts/_navigation.html.erb +14 -8
- data/app/views/layouts/application.html.erb +1 -3
- data/app/views/project_notification/test_run.html.erb +13 -3
- data/app/views/projects/_form.html.erb +13 -7
- data/app/views/triggers/index.html.erb +39 -0
- data/config/initializers/add_navigation_renderers.rb +0 -6
- data/config/initializers/houston_async.rb +4 -2
- data/config/initializers/houston_scheduler_daemon.rb +6 -0
- data/config/initializers/load_persistent_triggers.rb +7 -0
- data/config/initializers/requirements.rb +2 -1
- data/config/initializers/sync_commits_on_post_receive.rb +2 -2
- data/config/routes.rb +17 -15
- data/db/migrate/20160711170921_rename_jobs_to_actions.rb +5 -0
- data/db/migrate/20160713204605_add_trigger_and_params_to_actions.rb +6 -0
- data/db/migrate/20160715173039_create_persistent_triggers.rb +10 -0
- data/db/structure.sql +197 -221
- data/houston-core.gemspec +1 -1
- data/lib/houston/boot/actions.rb +105 -0
- data/lib/houston/boot/active_record_serializer.rb +24 -0
- data/lib/houston/boot/configuration.rb +118 -49
- data/lib/houston/boot/events.rb +46 -0
- data/lib/houston/boot/extensions.rb +118 -14
- data/lib/houston/boot/observer.rb +122 -24
- data/lib/houston/boot/readonly_hash_serializer.rb +15 -0
- data/lib/houston/boot/serializer.rb +83 -0
- data/lib/houston/boot/ticket_antecedent_serializer.rb +21 -0
- data/lib/houston/boot/timer.rb +45 -0
- data/lib/houston/boot/triggers.rb +75 -0
- data/lib/houston/boot.rb +5 -0
- data/lib/houston/version.rb +1 -1
- data/lib/params_serializer.rb +18 -0
- data/lib/tasks/actions.rake +12 -0
- data/lib/tasks/events.rake +11 -0
- data/templates/new-instance/config/abilities.rb +0 -8
- data/templates/new-instance/config/{triggers → events}/alerts/slack_when_assigned.rb +1 -1
- data/templates/new-instance/config/{triggers → events}/alerts/slack_when_opened.rb +1 -1
- data/templates/new-instance/config/{triggers → events}/daemons/health.rb +6 -6
- data/templates/new-instance/config/{triggers → events}/deploy/autoresolve_errs.rb +1 -1
- data/templates/new-instance/config/{triggers → events}/deploy/checkout_mentioned_alerts.rb +1 -1
- data/templates/new-instance/config/{triggers → events}/deploy/notify_deployer_when_finished.rb +2 -2
- data/templates/new-instance/config/{triggers → events}/github/publish_comments_on_slack.rb +9 -9
- data/templates/new-instance/config/{triggers → events}/tests/slack_when_analyzed.rb +1 -1
- data/templates/new-instance/config/{triggers → events}/tests/slack_when_completed.rb +1 -1
- data/templates/new-instance/config/{triggers → events}/tickets/mark_tasks_completed_on_commit.rb +1 -1
- data/templates/new-instance/config/main.rb +8 -35
- data/templates/new-instance/config/{jobs → timers}/cache_key_dependencies.rb +0 -0
- data/templates/new-instance/config/{jobs → timers}/email_about_open_alerts.rb +0 -0
- data/templates/new-instance/config/{jobs → timers}/purge_jobs.rb +0 -0
- data/templates/new-instance/config/{jobs → timers}/slack_reminders_about_alerts.rb +0 -0
- data/templates/new-instance/config/{jobs → timers}/sync_commits.rb +0 -0
- data/templates/new-instance/config/{jobs → timers}/sync_pull_requests.rb +0 -0
- data/templates/new-instance/config/{jobs → timers}/sync_tickets.rb +0 -0
- data/templates/new-module/lib/houston/%name%.rb +13 -0
- data/test/integration/ci_integration_test.rb +5 -5
- data/test/integration/web_hook_test.rb +1 -1
- data/test/test_helper.rb +14 -0
- data/test/unit/controllers/hooks_controller_test.rb +2 -2
- data/test/unit/initializers/sync_commits_on_post_receive_test.rb +1 -1
- data/test/unit/models/actions_test.rb +107 -0
- data/test/unit/models/configuration_test.rb +108 -0
- data/test/unit/models/observer_test.rb +87 -3
- data/test/unit/models/persistent_trigger_test.rb +94 -0
- data/test/unit/models/serializer_test.rb +80 -0
- data/test/unit/models/triggers_test.rb +53 -0
- metadata +60 -60
- data/app/assets/javascripts/houston/app/models/testing_note.coffee +0 -18
- data/app/assets/javascripts/houston/app/views/commit_view.coffee +0 -13
- data/app/assets/javascripts/houston/app/views/testing_note_view.coffee +0 -85
- data/app/assets/javascripts/houston/app/views/testing_report_view.coffee +0 -29
- data/app/assets/javascripts/houston/app/views/testing_ticket_view.coffee +0 -203
- data/app/assets/stylesheets/houston/application/jobs.scss +0 -5
- data/app/assets/stylesheets/houston/application/testing_report.scss +0 -279
- data/app/assets/templates/commit.hbs +0 -9
- data/app/assets/templates/testing_notes/edit.hbs +0 -20
- data/app/assets/templates/testing_notes/new.hbs +0 -27
- data/app/assets/templates/testing_notes/show.hbs +0 -11
- data/app/assets/templates/testing_report/description.hbs +0 -12
- data/app/assets/templates/testing_report/ticket.hbs +0 -21
- data/app/assets/templates/testing_report/verdict.hbs +0 -4
- data/app/controllers/jobs_controller.rb +0 -42
- data/app/controllers/testing_notes_controller.rb +0 -50
- data/app/controllers/testing_report_controller.rb +0 -38
- data/app/models/testing_note.rb +0 -64
- data/app/presenters/testing_note_presenter.rb +0 -27
- data/app/presenters/testing_report_ticket_presenter.rb +0 -71
- data/app/views/jobs/index.html.erb +0 -72
- data/app/views/jobs/show.html.erb +0 -41
- data/app/views/project_notification/testing_note.html.erb +0 -9
- data/app/views/testing_report/_scripts.html.erb +0 -12
- data/app/views/testing_report/index.html.erb +0 -31
- data/app/views/testing_report/show.html.erb +0 -29
- data/config/initializers/houston_scheduler.rb +0 -23
- data/db/migrate/20120424212706_create_testing_notes.rb +0 -14
- data/db/migrate/20120501231817_add_expires_at_to_testing_notes.rb +0 -5
- data/db/migrate/20120501231948_add_unfuddle_id_to_testing_notes.rb +0 -5
- data/db/migrate/20120715230526_change_testing_notes_comment_to_text.rb +0 -9
- data/db/migrate/20130211015046_add_min_passing_verdicts_to_projects.rb +0 -5
- data/db/migrate/20130407220039_add_project_id_to_testing_notes.rb +0 -26
- data/db/migrate/20140511024021_rename_testing_notes_unfuddle_id_to_remote_id.rb +0 -5
- data/templates/new-instance/config/triggers/tickets/email_testing_notes.rb +0 -7
- data/templates/new-instance/log/development.log +0 -41253
- data/templates/new-instance/log/test.log +0 -545
- 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,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}}
|
5
|
-
{{{linkToCommit this}}}
|
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,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
|