Provide a decoupled, consumer-driven system that triggers repository workflows when upstream repositories publish tags or releases, without requiring any changes to producer repositories (e.g., quark-compiler).
Forgejo Actions supports:
- Repo-local triggers (
push.tags,release) - Manual/API triggers (
workflow_dispatch)
It does not support:
- Cross-repo event subscriptions
- Platform-wide workflow triggers
Result: No native way for repo B to react to repo A’s release without coupling.
fordgejo-eventd introduces a local event routing service (forgejo-eventd) that:
- Receives all tag/release events via Forgejo org/system webhook.
- Normalizes events into a consistent internal format.
- Discovers consumer subscriptions defined inside repo workflows.
- Dispatches matching workflows via
workflow_dispatch.
Forgejo (org/system webhook)
→ forgejo-eventd (local service)
→ scan workflow metadata
→ match subscriptions
→ POST workflow_dispatch → consumer repo
- Producer-agnostic: upstream repos (e.g.,
quark-compiler) require zero changes - Consumer-owned subscriptions: each repo declares what it listens to
- Colocated definition: subscription is tied directly to the workflow it triggers
- No inference as source of truth: avoid relying on
flake.lockor comments
Inside workflow files in .forgejo/workflows/
x-quark-subscription:
version: 1
match:
repo: quark/quark-compiler
events:
- tag_pushed
- release_published
tag_pattern: '^v[0-9]+\.[0-9]+\.[0-9]+$'
dispatch:
workflow: refresh-compiler-input.yml
ref: main
inputs:
dependency_name: quark-compileron:
workflow_dispatch:
inputs:
source_repo:
type: string
required: true
source_event:
type: string
required: true
source_tag:
type: stringquark-compilerpublishes tag/release- Forgejo sends webhook →
forgejo-eventd forgejo-eventdnormalizes event:
{
"repo": "quark/quark-compiler",
"event": "release_published",
"tag": "v1.2.3"
}-
forgejo-eventdscans indexed subscriptions -
Matching workflows are dispatched via:
POST /repos/{owner}/{repo}/actions/workflows/{workflow}/dispatches
flake.lockinspection- Used for suggestions only, not triggering
- Sidecar metadata files
-
Fallback if Forgejo rejects unknown YAML keys:
workflow.yml
workflow.quark.yaml
-
- Webhook receiver (with signature validation)
- Subscription indexer (scans repos)
- Matcher (repo + event + tag pattern)
- Dispatcher (calls Forgejo API)
- Deduplication store (event_id + subscription_id)
- Relies on Forgejo webhooks (org or system scope)
- Uses
workflow_dispatchas the only cross-repo execution entrypoint - Custom metadata (
x-forgejo-eventd-subscription) is not native Forgejo syntax
- Workflow YAML tolerance
- Unknown keys (
x-forgejo-eventd-*) may not be officially supported → must test
- Unknown keys (
- Event duplication
- Requires explicit idempotency handling
- Token scope
- Service must hold credentials to dispatch workflows across repos
- Configure org-level webhook →
forgejo-eventd - Add one subscription to
quark-nix - Publish test tag in
quark-compiler - Confirm:
- event received
- subscription matched
- workflow dispatched exactly once