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.
Require a linked issue when a change request opens
0789f22ea633bf995417893c0052abb6a36d5520 · Keenan Nemetz · 9d ago · parent 1265ea55
Require a linked issue when a change request opens Add a per-repository policy for teams that want every proposed update to trace back to an issue. The browser marks Closes as required, and the pre-receive hook applies the same rule to requests added through the CLI or a hand-written metadata commit. Existing requests stay editable and landable.
server/admin_web_test.go +5−1
| @@ -28,7 +28,7 @@ func TestRepositoryAccessSettings(t *testing.T) { | |||
| 28 | 28 | if !strings.Contains(body, `id="access"`) { | |
| 29 | 29 | t.Fatalf("settings page has no access section:\n%s", body) | |
| 30 | 30 | } | |
| 31 | for _, want := range []string{"Default role", "Approvals required", "wilbur", "Runner"} { | ||
| 31 | for _, want := range []string{"Default role", "Approvals required", "Require a linked issue", "wilbur", "Runner"} { | ||
| 32 | 32 | if !strings.Contains(body, want) { | |
| 33 | 33 | t.Fatalf("access section does not show %q:\n%s", want, body) | |
| 34 | 34 | } | |
| @@ -43,6 +43,7 @@ func TestRepositoryAccessSettings(t *testing.T) { | |||
| 43 | 43 | "csrf": {sess.CSRF}, | |
| 44 | 44 | "default": {"read"}, | |
| 45 | 45 | "approvals": {"2"}, | |
| 46 | "require_linked_issue": {"on"}, | ||
| 46 | 47 | "protected": {"refs/heads/main\nrefs/heads/release/*"}, | |
| 47 | 48 | "role:" + f.ownerID: {"admin"}, | |
| 48 | 49 | "role:" + f.writerID: {"maintain"}, | |
| @@ -73,6 +74,9 @@ func TestRepositoryAccessSettings(t *testing.T) { | |||
| 73 | 74 | if acl.RequiresChecks() { | |
| 74 | 75 | t.Fatal("checks stayed required after an unchecked save") | |
| 75 | 76 | } | |
| 77 | if !acl.RequiresLinkedIssue() { | ||
| 78 | t.Fatal("linked-issue rule was not saved") | ||
| 79 | } | ||
| 76 | 80 | if got := strings.Join(acl.Protected, ","); got != "refs/heads/main,refs/heads/release/*" { | |
| 77 | 81 | t.Fatalf("protected = %q", got) | |
| 78 | 82 | } | |