Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

A free and open-source forge that lives in your Git repo.

Build out change review and threaded discussions

f6f4b1db24292d1df877680714952a9c568e2b78 · Keenan Nemetz · 15d ago · parent 564acd4b

Build out change review and threaded discussions

- Add Conversation, Files and Runs tabs to change requests. Files uses the
  code-browser shape with a changed-file tree and one selected-file diff;
  Runs lists the head commit's workflow results.
- Show anchored review comments beneath the line, with a collapsed excerpt
  read from the exact blob that was reviewed, and return posted anchors to
  their line note.
- Add comment threads: any comment can be replied to, the UI flattens the
  descendants under one root, reply context links back to the parent, and
  reply targets feed a single composer at the foot of the discussion.
- Collapse reply groups while keeping the root visible, and scroll to the
  composer when Reply is selected.
- Add comment context menus with Reply, Copy text, Copy link, Edit and
  Delete. Add web edit/delete routes with author or admin checks; deletion
  leaves a tombstone so replies keep their thread.
- Support --reply-to in the issue and change CLI commands, and treat a
  missing parent as a tombstone rather than an invalid tree.
- Fix the diff comment gutter, action button colours, reply labels, and
  keep the Files tree and diff pane aligned.

Update metadata validation, web templates, CSS, JavaScript, tests, and the
CLI/change-request/issue docs.

server/web/request_runs.go +59

@@ -0,0 +1,59 @@
1 package web
2
3 // The Runs tab shows the workflow results recorded for the commit under review.
4 // It is the same queue history as the repository Runs page, narrowed to the
5 // change's head so a reviewer does not have to search for the matching commits.
6
7 import (
8 "net/http"
9 "sort"
10
11 "github.com/rodent-software/vole/ci/runs"
12 "github.com/rodent-software/vole/metadata"
13 )
14
15 type requestRunsView struct {
16 requestSidebarView
17 Tab string
18 FileCount int
19 Runs []*runs.Run
20 }
21
22 // RequestRuns serves the Runs tab for one change.
23 func (w *Web) RequestRuns(rw http.ResponseWriter, r *http.Request) {
24 m, ok := w.open(rw, r)
25 if !ok {
26 return
27 }
28 req, err := metadata.GetRequest(m.Git(), r.PathValue("id"))
29 if err != nil {
30 http.NotFound(rw, r)
31 return
32 }
33
34 var results []*runs.Run
35 if w.Runs != nil && req.Head != "" {
36 if byKey, err := w.Runs.ForSHA(m.Name, req.Head); err == nil {
37 results = make([]*runs.Run, 0, len(byKey))
38 for _, run := range byKey {
39 results = append(results, run)
40 }
41 sort.Slice(results, func(i, j int) bool {
42 if results[i].Workflow != results[j].Workflow {
43 return results[i].Workflow < results[j].Workflow
44 }
45 return results[i].Job < results[j].Job
46 })
47 } else {
48 w.Logger("request runs %s: %v", req.ID, err)
49 }
50 }
51 files, _, _ := w.requestDiff(m, req)
52
53 w.render(rw, "request_runs", requestRunsView{
54 requestSidebarView: w.requestSidebar(r, m, req, m.Name+" · "+req.Title+" · runs", ""),
55 Tab: "runs",
56 FileCount: len(files),
57 Runs: results,
58 }, 0)
59 }