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.

Add event, schedule and manual workflow triggers

eb07ff5696e0d83201215966e3ea1e6a24467581 · Keenan Nemetz · 8d ago · parent 1cde8b9e

Add event, schedule and manual workflow triggers

Workflows can now react to change requests, issues, comments, cron
schedules and manual runs, and a push trigger can filter by the paths it
changed. Branch and tag patterns gain ! exclusion.

Event runs are pinned with a JSON payload and the runner exposes it as
VOLE_EVENT, VOLE_EVENT_ACTION and VOLE_EVENT_PATH. Change-request runs
check out the base tip and carry the head and changed files, so an event
never executes an unapproved contributor commit.

Workflow dispatch resolves typed inputs and is available from the
workflows page and `vole workflow dispatch`. Deduplication now includes
an occurrence so the same commit can run for a later event or schedule
slot while a push remains idempotent.

Part of: #138

ci/agent/agent.go +31−1

@@ -70,6 +70,12 @@ type runnerJob struct {
70 70 Workflow string `json:"workflow"`
71 71 Job string `json:"job"`
72 72 Steps []runnerStep `json:"steps"`
73 // Trigger and EventPayload are the pinned event that requested this run. The
74 // runner writes the payload into a file and sets VOLE_EVENT, VOLE_EVENT_ACTION
75 // and VOLE_EVENT_PATH; it is data, never an interpolated command.
76 Trigger string `json:"trigger,omitempty"`
77 TriggerAction string `json:"trigger_action,omitempty"`
78 EventPayload string `json:"event_payload,omitempty"`
73 79 // Image is a registry reference or "file:<name>". For the latter, ImageDefinition
74 80 // is the pinned recipe and ImageSHA its digest; the runner builds it locally.
75 81 Image string `json:"image"`
@@ -523,6 +529,30 @@ func (s *runnerSession) run(remote, cache string, job *runnerJob, lease time.Dur
523 529 return
524 530 }
525 531 mounts := s.cacheFor(job)
532 // An event run gets its pinned payload as a mounted file, not as an interpolated
533 // command. The workflow reads it deliberately, and a large issue or comment body
534 // cannot make the environment argument oversized.
535 env := job.Env
536 if job.EventPayload != "" {
537 eventDir := filepath.Join(filepath.Dir(co.Work), "event-"+job.ID+"-"+fmt.Sprint(job.Attempt))
538 if err := os.MkdirAll(eventDir, 0o700); err != nil {
539 fail("cannot prepare the event payload: %s", err)
540 return
541 }
542 defer os.RemoveAll(eventDir)
543 if err := os.WriteFile(filepath.Join(eventDir, "event.json"), []byte(job.EventPayload), 0o600); err != nil {
544 fail("cannot write the event payload: %s", err)
545 return
546 }
547 mounts = append(mounts, container.Mount{Host: eventDir, Path: "/run/vole"})
548 env = make(map[string]string, len(job.Env)+3)
549 for name, value := range job.Env {
550 env[name] = value
551 }
552 env["VOLE_EVENT"] = job.Trigger
553 env["VOLE_EVENT_ACTION"] = job.TriggerAction
554 env["VOLE_EVENT_PATH"] = "/run/vole/event.json"
555 }
526 556 if s.cacheRoot != "" {
527 557 defer func() {
528 558 if !s.cacheReuse {
@@ -542,7 +572,7 @@ func (s *runnerSession) run(remote, cache string, job *runnerJob, lease time.Dur
542 572 Work: co.Work,
543 573 Labels: box.labels(job),
544 574 Mounts: mounts,
545 Env: job.Env,
575 Env: env,
546 576 })
547 577 if err != nil {
548 578 fail("%s", err)