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/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.

cmd/vole/acl.go +30−1

@@ -24,6 +24,9 @@ const aclUsage = `usage: vole admin acl <command> [options] [args]
24 24 checks enable <repo>
25 25 checks disable <repo>
26 26
27 require-issues enable <repo>
28 require-issues disable <repo>
29
27 30 protect list <repo>
28 31 protect add <repo> <ref-pattern>...
29 32 protect remove <repo> <ref-pattern>...
@@ -65,7 +68,7 @@ func cmdACL(args []string) error {
65 68 }
66 69 switch sub {
67 70 case "show", "set-role", "set-default-role", "set-approvals",
68 "checks", "protect", "runners":
71 "checks", "require-issues", "protect", "runners":
69 72 default:
70 73 fmt.Fprintln(os.Stderr, aclUsage)
71 74 return usagef("unknown acl subcommand %q", sub)
@@ -128,6 +131,15 @@ func cmdACL(args []string) error {
128 131 return usagef("checks takes enable or disable, not %q", action)
129 132 }
130 133
134 case "require-issues":
135 if len(f.rest) != 2 {
136 return usageErr{msg: "usage: vole admin acl require-issues enable|disable <repo>"}
137 }
138 action, repo = f.rest[0], f.rest[1]
139 if action != "enable" && action != "disable" {
140 return usagef("require-issues takes enable or disable, not %q", action)
141 }
142
131 143 case "protect", "runners":
132 144 if len(f.rest) < 2 {
133 145 return usageErr{msg: fmt.Sprintf("usage: vole admin acl %s list|add|remove|set|clear <repo> ...", sub)}
@@ -186,6 +198,11 @@ func cmdACL(args []string) error {
186 198 if len(a.Protected) > 0 {
187 199 fmt.Printf("protected: %s\n", strings.Join(a.Protected, ", "))
188 200 }
201 if a.RequiresLinkedIssue() {
202 fmt.Println("linked issues: required for new change requests")
203 } else {
204 fmt.Println("linked issues: optional for new change requests")
205 }
189 206 // Admins are implicit runners, so an empty list is not "nobody": it is
190 207 // "nobody beyond the people who can edit this file".
191 208 if len(a.Runners) == 0 {
@@ -246,6 +263,18 @@ func cmdACL(args []string) error {
246 263 }
247 264 return nil
248 265
266 case "require-issues":
267 a.RequireLinkedIssue = action == "enable"
268 if err := save(); err != nil {
269 return err
270 }
271 if a.RequiresLinkedIssue() {
272 fmt.Println("linked issues: required when a change request is opened")
273 } else {
274 fmt.Println("linked issues: no longer required for new change requests")
275 }
276 return nil
277
249 278 case "protect":
250 279 if action == "list" {
251 280 printProtected(a, m.Name)