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.
Filter workflow events by mentions and assignment
727df38613897e6ffd56e1df05a2f674174bf547 · Keenan Nemetz · 8d ago · parent eb07ff56
Filter workflow events by mentions and assignment Add mentioned, replied-to, assigned-to, and author filters to issue, comment, and change-request triggers. Move the role vocabulary into core/role so author.role is validated without importing the access store, and pin mentions, reply authors, and assignee changes in the event payload.
server/events_test.go +66
| @@ -199,3 +199,69 @@ jobs: | |||
| 199 | 199 | t.Fatalf("dispatch branch = %q", run.Branch) | |
| 200 | 200 | } | |
| 201 | 201 | } | |
| 202 | |||
| 203 | func TestFilteredEventTriggersQueueOnlyMatchingRuns(t *testing.T) { | ||
| 204 | t.Parallel() | ||
| 205 | f := newFixture(t) | ||
| 206 | f.publish(f.repo) | ||
| 207 | f.addWriter(t) // wilbur, the account the agent filters name | ||
| 208 | work, _ := f.cloneWithChange(t, workflowFile(`version: 1 | ||
| 209 | on: | ||
| 210 | issue: | ||
| 211 | types: [opened, assigned] | ||
| 212 | assigned-to: [wilbur] | ||
| 213 | author: | ||
| 214 | role: maintain | ||
| 215 | comment: | ||
| 216 | types: [created] | ||
| 217 | mentioned: [wilbur] | ||
| 218 | replied-to: [wilbur] | ||
| 219 | author: | ||
| 220 | name: [keenan] | ||
| 221 | role: maintain | ||
| 222 | jobs: | ||
| 223 | respond: | ||
| 224 | image: alpine:3.22 | ||
| 225 | steps: | ||
| 226 | - run: cat "$VOLE_EVENT_PATH" | ||
| 227 | `), "ci") | ||
| 228 | if _, errs, err := f.git(work, "push", f.sshURL(f.repo), "HEAD:refs/heads/main"); err != nil { | ||
| 229 | t.Fatalf("push: %s", errs) | ||
| 230 | } | ||
| 231 | |||
| 232 | out, errs, err := f.cli(work, "issue", "new", "--title", "Assigned at creation", | ||
| 233 | "-m", "No mention here.", "-a", "wilbur") | ||
| 234 | if err != nil { | ||
| 235 | t.Fatalf("issue new: %v\n%s", err, errs) | ||
| 236 | } | ||
| 237 | assignedID := strings.Fields(out)[0] | ||
| 238 | f.waitForRun(t, 5*time.Second, func(r *runs.Run) bool { | ||
| 239 | return r.Trigger == "issue" && r.TriggerAction == "opened" && | ||
| 240 | strings.Contains(r.EventPayload, `"id":"`+assignedID+`"`) | ||
| 241 | }) | ||
| 242 | |||
| 243 | out, errs, err = f.cli(work, "issue", "comment", assignedID, "-m", "@wilbur please take this.") | ||
| 244 | if err != nil { | ||
| 245 | t.Fatalf("issue comment: %v\n%s", err, errs) | ||
| 246 | } | ||
| 247 | f.waitForRun(t, 5*time.Second, func(r *runs.Run) bool { | ||
| 248 | return r.Trigger == "comment" && r.TriggerAction == "created" && | ||
| 249 | strings.Contains(r.EventPayload, `"id":"`+assignedID+`"`) && | ||
| 250 | strings.Contains(r.EventPayload, `"mentions":["wilbur"]`) | ||
| 251 | }) | ||
| 252 | |||
| 253 | out, errs, err = f.cli(work, "issue", "new", "--title", "Assigned later", | ||
| 254 | "-m", "Plain body.") | ||
| 255 | if err != nil { | ||
| 256 | t.Fatalf("issue new (no push): %v\n%s", err, errs) | ||
| 257 | } | ||
| 258 | plainID := strings.Fields(out)[0] | ||
| 259 | if _, errs, err := f.cli(work, "issue", "assign", plainID, "wilbur"); err != nil { | ||
| 260 | t.Fatalf("issue assign: %v\n%s", err, errs) | ||
| 261 | } | ||
| 262 | f.waitForRun(t, 5*time.Second, func(r *runs.Run) bool { | ||
| 263 | return r.Trigger == "issue" && r.TriggerAction == "assigned" && | ||
| 264 | strings.Contains(r.EventPayload, `"id":"`+plainID+`"`) && | ||
| 265 | strings.Contains(r.EventPayload, `"assignees_added":["wilbur"]`) | ||
| 266 | }) | ||
| 267 | } | ||