vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Give workflows and jobs a name and description
1cde8b9ea2ba1483beb90f19cde0f58aede2a661 · Keenan Nemetz · 8d ago · parent 30de4a44
Give workflows and jobs a name and description The workflows page showed the file path and job IDs, so a reader had to open the YAML comments to learn what a workflow was for. Add optional top-level and job-level name and description fields, default them to the file stem and job ID, pin them with a queued run, and show them on the workflows and run pages. Also document what the workflow format still cannot express, and state that CI jobs are independent and unordered: only a local run uses the declaration order. Part of: #138
server/workflows_test.go +26−2
| @@ -15,11 +15,15 @@ func TestWorkflowListAndRunActions(t *testing.T) { | |||
| 15 | 15 | f.publish(f.repo) | |
| 16 | 16 | work := workRepo(t, map[string]string{ | |
| 17 | 17 | ".vole/workflows/ci.yaml": `version: 1 | |
| 18 | name: Verify main | ||
| 19 | description: Build and test every push. | ||
| 18 | 20 | on: | |
| 19 | 21 | push: | |
| 20 | 22 | branches: [main] | |
| 21 | 23 | jobs: | |
| 22 | 24 | test: | |
| 25 | name: Unit tests | ||
| 26 | description: Runs the test suite. | ||
| 23 | 27 | image: alpine:3.22 | |
| 24 | 28 | steps: | |
| 25 | 29 | - name: build | |
| @@ -30,6 +34,23 @@ jobs: | |||
| 30 | 34 | t.Fatalf("push: %s", errs) | |
| 31 | 35 | } | |
| 32 | 36 | ||
| 37 | pushed := f.waitForRun(t, 5*time.Second, func(r *runs.Run) bool { | ||
| 38 | return r.Job == "test" && r.WorkflowName != "" | ||
| 39 | }) | ||
| 40 | if pushed.WorkflowName != "Verify main" || pushed.WorkflowDescription != "Build and test every push." || | ||
| 41 | pushed.JobName != "Unit tests" || pushed.JobDescription != "Runs the test suite." { | ||
| 42 | t.Fatalf("pinned display metadata = %+v", pushed) | ||
| 43 | } | ||
| 44 | code, body := f.get("/r/" + f.repo + "/runs/" + pushed.ID) | ||
| 45 | if code != 200 { | ||
| 46 | t.Fatalf("pushed run page = %d", code) | ||
| 47 | } | ||
| 48 | for _, want := range []string{"Run · Unit tests", "Verify main", "Build and test every push.", "Runs the test suite."} { | ||
| 49 | if !strings.Contains(body, want) { | ||
| 50 | t.Fatalf("run page does not show %q:\n%s", want, body) | ||
| 51 | } | ||
| 52 | } | ||
| 53 | |||
| 33 | 54 | enqueue := func(id, status string) { | |
| 34 | 55 | run := runs.Run{ | |
| 35 | 56 | ID: id, Repo: f.repo, Ref: "refs/heads/main", Branch: "main", | |
| @@ -47,11 +68,14 @@ jobs: | |||
| 47 | 68 | } | |
| 48 | 69 | enqueue("01M5R8XR12EZ5WYJDM0F1928D1", runs.StatusQueued) | |
| 49 | 70 | ||
| 50 | code, body := f.get("/r/" + f.repo + "/workflows") | ||
| 71 | code, body = f.get("/r/" + f.repo + "/workflows") | ||
| 51 | 72 | if code != 200 { | |
| 52 | 73 | t.Fatalf("workflows page = %d", code) | |
| 53 | 74 | } | |
| 54 | for _, want := range []string{".vole/workflows/ci.yaml", "test", "alpine:3.22", "any runner", "queued"} { | ||
| 75 | for _, want := range []string{ | ||
| 76 | "Verify main", "Build and test every push.", ".vole/workflows/ci.yaml", | ||
| 77 | "Unit tests", "Runs the test suite.", "test", "alpine:3.22", "any runner", "queued", | ||
| 78 | } { | ||
| 55 | 79 | if !strings.Contains(body, want) { | |
| 56 | 80 | t.Fatalf("workflows page does not show %q:\n%s", want, body) | |
| 57 | 81 | } | |