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.

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 }