Skip to content

feat: EventBus-triggered pipeline execution via inline eventbus trigger type#314

Merged
intel352 merged 5 commits intomainfrom
copilot/add-eventbus-trigger-pipeline
Mar 12, 2026
Merged

feat: EventBus-triggered pipeline execution via inline eventbus trigger type#314
intel352 merged 5 commits intomainfrom
copilot/add-eventbus-trigger-pipeline

Conversation

Copy link
Contributor

Copilot AI commented Mar 12, 2026

Pipelines had no way to react to EventBus messages — the EventBusTrigger module existed but couldn't be wired via inline pipeline trigger config, making event-driven fan-out patterns impossible without workarounds.

Changes

  • plugins/messaging/plugin.go: Added PipelineTriggerConfigWrapper for the eventbus trigger type, converting flat pipeline config (topic, event, async) into EventBusTrigger's native subscriptions format. Also fixes the event wrapper to inject a default action: "execute" — previously omitted, which would cause EventTrigger.Configure to fail at runtime.

  • plugins/messaging/plugin_test.go: Tests for both event and eventbus config wrappers, covering topic, event filter, and async passthrough.

  • engine_pipeline_test.go: TestPipeline_ConfigurePipelines_InlineEventBusTrigger verifying the eventbus trigger type is correctly matched and configured during pipeline setup.

Usage

pipelines:
  process-follow-up-event:
    trigger:
      type: eventbus
      config:
        topic: follow-up.created
        event: follow-up.created  # optional event-type filter
        async: true               # optional async delivery
    steps:
      - name: process
        type: step.log
        config:
          message: "EventBus event received"

The wrapper translates this into the EventBusTrigger subscriptions format, routing messages to pipeline:process-follow-up-event with action execute.

Original prompt

This section details on the original issue you should resolve

<issue_title>Feature: EventBus-triggered pipeline execution</issue_title>
<issue_description>## Summary

Pipelines can currently be triggered by HTTP requests, schedules (cron), and CLI invocation. There is no trigger type for EventBus messages — meaning pipelines cannot react to events published by other pipelines or external systems via the modular EventBus.

Use Case

Event-driven architectures need pipelines that fire when a message arrives on a topic:

pipelines:
  process-follow-up-event:
    trigger:
      type: event
      config:
        topic: follow-up.created
        group: chimera-processor   # consumer group for at-least-once
    steps:
      - name: decrypt
        type: step.event_decrypt
        config:
          key_id: "${KMS_KEY_ARN}"
      - name: process
        type: step.db_exec
        config:
          # ... process the event

This enables fan-out patterns: an API pipeline publishes an event, and one or more event-triggered pipelines consume it asynchronously.

Current State

  • step.event_publish can publish to the EventBus
  • The Bento plugin (bento.input) can bridge external sources INTO the EventBus
  • Nothing bridges EventBus messages into pipeline execution

The Bento plugin gets events onto the bus, but there's no trigger.event to invoke a pipeline when a message arrives.

Proposed Approach

New trigger type event (or eventbus):

trigger:
  type: event
  config:
    topic: "follow-up.*"    # wildcard support (already in KinesisEventBus)
    group: "consumer-group"  # for competing consumers
    batch_size: 1            # optional batching
    retry:
      max_attempts: 3
      backoff: "1s"

The trigger would:

  1. Subscribe to the configured topic via the EventBus interface
  2. On message receipt, create a pipeline execution context with the event data accessible as trigger.event
  3. Support consumer groups for horizontal scaling
  4. Handle acknowledgment after successful pipeline completion

Alternatives

  • Bento plugin bento.input → HTTP webhook → HTTP trigger: Works but adds unnecessary HTTP hop and latency
  • Custom Go consumer outside workflow: Defeats the purpose of declarative pipelines</issue_description>

Comments on the Issue (you are @copilot in this section)


📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.

Add PipelineTriggerConfigWrapper for 'eventbus' trigger type in the
messaging plugin, enabling inline EventBus-triggered pipeline execution.

Also fix the existing 'event' wrapper to set default action "execute",
which is required by EventTrigger.Configure.

Users can now configure event-driven pipelines as:

  pipelines:
    process-follow-up-event:
      trigger:
        type: eventbus
        config:
          topic: follow-up.created
      steps:
        - ...

The wrapper converts the flat config into the EventBusTrigger's native
subscriptions format, mapping the pipeline name to workflow/action.

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
Copilot AI changed the title [WIP] Add EventBus-triggered pipeline execution feat: EventBus-triggered pipeline execution via inline eventbus trigger type Mar 12, 2026
@intel352 intel352 marked this pull request as ready for review March 12, 2026 15:59
Copilot AI review requested due to automatic review settings March 12, 2026 15:59
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds inline pipeline trigger support for EventBus-driven execution by introducing an eventbus pipeline trigger config wrapper in the messaging plugin, enabling event-driven pipeline fan-out patterns.

Changes:

  • Add eventbus pipeline trigger config wrapper (and fix event wrapper to inject default action: "execute").
  • Add unit tests for event and eventbus wrapper outputs (topic/event/async/action/workflow mapping).
  • Add an engine-level pipeline configuration test for inline eventbus trigger matching/configure invocation.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
plugins/messaging/plugin.go Adds/updates pipeline trigger config wrappers for event and eventbus, ensuring action: execute is present and config is translated into subscriptions format.
plugins/messaging/plugin_test.go Adds tests validating wrapper registration and wrapper output structure for event/eventbus.
engine_pipeline_test.go Adds coverage that inline eventbus triggers are matched and Configure() is invoked during pipeline configuration.

Comment on lines +333 to +336
p := New()
wrappers := p.PipelineTriggerConfigWrappers()
wrapper := wrappers["eventbus"]

Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test pulls wrapper := wrappers["eventbus"] without checking the key exists; if the wrapper is missing, the test will panic with a nil-function call instead of producing a clear assertion failure. Capture the boolean (wrapper, ok := ...) and t.Fatal when it’s missing.

Copilot uses AI. Check for mistakes.
Comment on lines +332 to +379
func TestPipeline_ConfigurePipelines_InlineEventBusTrigger(t *testing.T) {
// Use a minimal engine without plugins to avoid trigger collisions.
app := newMockApplication()
engine := NewStdEngine(app, app.Logger())
engine.AddStepType("step.log", module.NewLogStepFactory())
pipelineHandler := handlers.NewPipelineWorkflowHandler()
engine.RegisterWorkflowHandler(pipelineHandler)

// Register a mock trigger that responds to "eventbus" type
mt := &mockTrigger{
name: module.EventBusTriggerName,
configType: "eventbus",
}
engine.RegisterTrigger(mt)

pipelineCfg := map[string]any{
"process-follow-up-event": map[string]any{
"trigger": map[string]any{
"type": "eventbus",
"config": map[string]any{
"topic": "follow-up.created",
},
},
"steps": []any{
map[string]any{
"name": "log-event",
"type": "step.log",
"config": map[string]any{
"level": "info",
"message": "EventBus event received",
},
},
},
},
}

err := engine.configurePipelines(pipelineCfg)
if err != nil {
t.Fatalf("configurePipelines failed: %v", err)
}

if !pipelineHandler.CanHandle("process-follow-up-event") {
t.Error("expected pipeline to be registered")
}

if !mt.configuredCalled {
t.Error("expected eventbus trigger to be configured")
}
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestPipeline_ConfigurePipelines_InlineEventBusTrigger currently only verifies that a trigger with configType "eventbus" gets Configure() called; it does not verify that the inline flat config was wrapped into the EventBusTrigger native subscriptions format (including the injected default action: execute). Consider capturing the config passed to the mock trigger and asserting it contains subscriptions[0].workflow == "pipeline:process-follow-up-event" and subscriptions[0].action == "execute", and/or registering the wrapper via engine.RegisterTriggerConfigWrapper("eventbus", ...) / engine.LoadPlugin(messaging.New()) so this test actually exercises the wrapper integration.

Copilot generated this review using guidance from organization custom instructions.
Comment on lines +303 to +306
p := New()
wrappers := p.PipelineTriggerConfigWrappers()
wrapper := wrappers["eventbus"]

Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test pulls wrapper := wrappers["eventbus"] without checking the key exists; if the wrapper is missing, the test will panic with a nil-function call instead of producing a clear assertion failure. Capture the boolean (wrapper, ok := ...) and t.Fatal when it’s missing.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link

github-actions bot commented Mar 12, 2026

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:244: parsing iteration count: invalid syntax
baseline-bench.txt:302978: parsing iteration count: invalid syntax
baseline-bench.txt:610545: parsing iteration count: invalid syntax
baseline-bench.txt:913753: parsing iteration count: invalid syntax
baseline-bench.txt:1213301: parsing iteration count: invalid syntax
baseline-bench.txt:1523895: parsing iteration count: invalid syntax
benchmark-results.txt:244: parsing iteration count: invalid syntax
benchmark-results.txt:306935: parsing iteration count: invalid syntax
benchmark-results.txt:612357: parsing iteration count: invalid syntax
benchmark-results.txt:1120042: parsing iteration count: invalid syntax
benchmark-results.txt:1410608: parsing iteration count: invalid syntax
benchmark-results.txt:1703775: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 7763 64-Core Processor                
                            │ baseline-bench.txt │       benchmark-results.txt        │
                            │       sec/op       │    sec/op     vs base              │
InterpreterCreation-4               6.684m ± 70%   6.983m ± 57%       ~ (p=0.937 n=6)
ComponentLoad-4                     3.493m ±  1%   3.510m ±  8%       ~ (p=0.818 n=6)
ComponentExecute-4                  2.017µ ±  2%   2.010µ ±  2%       ~ (p=0.485 n=6)
PoolContention/workers-1-4          1.090µ ±  3%   1.098µ ±  1%       ~ (p=0.574 n=6)
PoolContention/workers-2-4          1.090µ ±  1%   1.091µ ±  1%       ~ (p=0.844 n=6)
PoolContention/workers-4-4          1.094µ ±  1%   1.098µ ±  1%       ~ (p=0.329 n=6)
PoolContention/workers-8-4          1.089µ ±  1%   1.107µ ±  2%  +1.65% (p=0.004 n=6)
PoolContention/workers-16-4         1.103µ ±  2%   1.104µ ±  1%       ~ (p=0.699 n=6)
ComponentLifecycle-4                3.581m ±  0%   3.545m ±  4%       ~ (p=0.132 n=6)
SourceValidation-4                  2.399µ ±  1%   2.308µ ±  1%  -3.77% (p=0.002 n=6)
RegistryConcurrent-4                831.5n ±  3%   769.1n ±  3%  -7.50% (p=0.002 n=6)
LoaderLoadFromString-4              3.613m ±  2%   3.682m ±  2%       ~ (p=0.240 n=6)
geomean                             18.76µ         18.71µ        -0.28%

                            │ baseline-bench.txt │        benchmark-results.txt         │
                            │        B/op        │     B/op      vs base                │
InterpreterCreation-4               1.944Mi ± 0%   1.944Mi ± 0%       ~ (p=0.784 n=6)
ComponentLoad-4                     2.097Mi ± 0%   2.097Mi ± 0%       ~ (p=0.485 n=6)
ComponentExecute-4                  1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4          1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4         1.203Ki ± 0%   1.203Ki ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                2.099Mi ± 0%   2.099Mi ± 0%       ~ (p=0.734 n=6)
SourceValidation-4                  1.984Ki ± 0%   1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                1.133Ki ± 0%   1.133Ki ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4              2.099Mi ± 0%   2.099Mi ± 0%       ~ (p=0.461 n=6)
geomean                             15.05Ki        15.05Ki       +0.00%
¹ all samples are equal

                            │ baseline-bench.txt │        benchmark-results.txt        │
                            │     allocs/op      │  allocs/op   vs base                │
InterpreterCreation-4                15.09k ± 0%   15.09k ± 0%       ~ (p=1.000 n=6)
ComponentLoad-4                      17.43k ± 0%   17.43k ± 0%       ~ (p=1.000 n=6)
ComponentExecute-4                    25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-1-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-2-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-4-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-8-4            25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
PoolContention/workers-16-4           25.00 ± 0%    25.00 ± 0%       ~ (p=1.000 n=6) ¹
ComponentLifecycle-4                 17.48k ± 0%   17.48k ± 0%       ~ (p=1.000 n=6) ¹
SourceValidation-4                    32.00 ± 0%    32.00 ± 0%       ~ (p=1.000 n=6) ¹
RegistryConcurrent-4                  2.000 ± 0%    2.000 ± 0%       ~ (p=1.000 n=6) ¹
LoaderLoadFromString-4               17.47k ± 0%   17.47k ± 0%       ~ (p=1.000 n=6) ¹
geomean                               181.2         181.2       +0.00%
¹ all samples are equal

pkg: github.com/GoCodeAlone/workflow/middleware
                                  │ baseline-bench.txt │       benchmark-results.txt       │
                                  │       sec/op       │   sec/op     vs base              │
CircuitBreakerDetection-4                  286.5n ± 1%   288.9n ± 1%  +0.86% (p=0.002 n=6)
CircuitBreakerExecution_Success-4          22.49n ± 1%   22.50n ± 1%       ~ (p=0.526 n=6)
CircuitBreakerExecution_Failure-4          65.21n ± 0%   64.52n ± 0%  -1.06% (p=0.002 n=6)
geomean                                    74.90n        74.86n       -0.06%

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │        B/op        │    B/op     vs base                │
CircuitBreakerDetection-4                 144.0 ± 0%     144.0 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │       benchmark-results.txt        │
                                  │     allocs/op      │ allocs/op   vs base                │
CircuitBreakerDetection-4                 1.000 ± 0%     1.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Success-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
CircuitBreakerExecution_Failure-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                              ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
                                 │ baseline-bench.txt │        benchmark-results.txt        │
                                 │       sec/op       │    sec/op      vs base              │
JQTransform_Simple-4                     888.0n ± 25%   1018.9n ± 18%       ~ (p=0.093 n=6)
JQTransform_ObjectConstruction-4         1.459µ ±  1%    1.537µ ±  1%  +5.35% (p=0.002 n=6)
JQTransform_ArraySelect-4                3.299µ ±  0%    3.573µ ±  1%  +8.32% (p=0.002 n=6)
JQTransform_Complex-4                    38.00µ ±  1%    39.72µ ±  1%  +4.51% (p=0.002 n=6)
JQTransform_Throughput-4                 1.784µ ±  1%    1.873µ ±  1%  +4.96% (p=0.002 n=6)
SSEPublishDelivery-4                     61.94n ±  8%    62.06n ±  1%       ~ (p=0.589 n=6)
geomean                                  1.618µ          1.719µ        +6.26%

                                 │ baseline-bench.txt │        benchmark-results.txt         │
                                 │        B/op        │     B/op      vs base                │
JQTransform_Simple-4                   1.273Ki ± 0%     1.273Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4       1.773Ki ± 0%     1.773Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4              2.625Ki ± 0%     2.625Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                  16.22Ki ± 0%     16.22Ki ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4               1.984Ki ± 0%     1.984Ki ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%       0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²                 +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │       benchmark-results.txt        │
                                 │     allocs/op      │ allocs/op   vs base                │
JQTransform_Simple-4                     10.00 ± 0%     10.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ObjectConstruction-4         15.00 ± 0%     15.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_ArraySelect-4                30.00 ± 0%     30.00 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Complex-4                    324.0 ± 0%     324.0 ± 0%       ~ (p=1.000 n=6) ¹
JQTransform_Throughput-4                 17.00 ± 0%     17.00 ± 0%       ~ (p=1.000 n=6) ¹
SSEPublishDelivery-4                     0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                             ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
                                    │ baseline-bench.txt │       benchmark-results.txt       │
                                    │       sec/op       │   sec/op     vs base              │
SchemaValidation_Simple-4                    1.117µ ± 3%   1.107µ ± 9%       ~ (p=0.937 n=6)
SchemaValidation_AllFields-4                 1.694µ ± 6%   1.683µ ± 6%       ~ (p=0.619 n=6)
SchemaValidation_FormatValidation-4          1.609µ ± 2%   1.623µ ± 2%       ~ (p=0.589 n=6)
SchemaValidation_ManySchemas-4               1.842µ ± 2%   1.843µ ± 4%       ~ (p=0.900 n=6)
geomean                                      1.538µ        1.536µ       -0.13%

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │        B/op        │    B/op     vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │       benchmark-results.txt        │
                                    │     allocs/op      │ allocs/op   vs base                │
SchemaValidation_Simple-4                   0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_AllFields-4                0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_FormatValidation-4         0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
SchemaValidation_ManySchemas-4              0.000 ± 0%     0.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                                                ²               +0.00%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │       sec/op       │    sec/op     vs base               │
EventStoreAppend_InMemory-4                1.278µ ± 12%   1.292µ ±  7%        ~ (p=0.513 n=6)
EventStoreAppend_SQLite-4                  1.788m ±  3%   1.823m ± 18%        ~ (p=0.485 n=6)
GetTimeline_InMemory/events-10-4           13.94µ ±  2%   15.00µ ±  4%   +7.56% (p=0.002 n=6)
GetTimeline_InMemory/events-50-4           78.56µ ±  2%   82.53µ ±  5%   +5.05% (p=0.026 n=6)
GetTimeline_InMemory/events-100-4          125.5µ ±  1%   162.8µ ± 10%  +29.68% (p=0.002 n=6)
GetTimeline_InMemory/events-500-4          643.2µ ±  1%   661.8µ ±  1%   +2.89% (p=0.002 n=6)
GetTimeline_InMemory/events-1000-4         1.318m ±  1%   1.361m ±  1%   +3.30% (p=0.002 n=6)
GetTimeline_SQLite/events-10-4             110.2µ ±  1%   114.6µ ±  2%   +4.04% (p=0.002 n=6)
GetTimeline_SQLite/events-50-4             251.5µ ±  0%   265.9µ ±  1%   +5.74% (p=0.002 n=6)
GetTimeline_SQLite/events-100-4            425.0µ ±  1%   455.5µ ±  2%   +7.17% (p=0.002 n=6)
GetTimeline_SQLite/events-500-4            1.810m ±  1%   1.871m ±  1%   +3.40% (p=0.002 n=6)
GetTimeline_SQLite/events-1000-4           3.529m ±  1%   3.677m ±  2%   +4.17% (p=0.002 n=6)
geomean                                    228.3µ         242.2µ         +6.11%

                                   │ baseline-bench.txt │        benchmark-results.txt         │
                                   │        B/op        │     B/op      vs base                │
EventStoreAppend_InMemory-4                  803.5 ± 7%     798.5 ± 8%       ~ (p=1.000 n=6)
EventStoreAppend_SQLite-4                  1.982Ki ± 2%   1.988Ki ± 2%       ~ (p=0.210 n=6)
GetTimeline_InMemory/events-10-4           7.953Ki ± 0%   7.953Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4           46.62Ki ± 0%   46.62Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4          94.48Ki ± 0%   94.48Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4          472.8Ki ± 0%   472.8Ki ± 0%       ~ (p=0.545 n=6)
GetTimeline_InMemory/events-1000-4         944.3Ki ± 0%   944.3Ki ± 0%       ~ (p=0.121 n=6)
GetTimeline_SQLite/events-10-4             16.74Ki ± 0%   16.74Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4             87.14Ki ± 0%   87.14Ki ± 0%       ~ (p=1.000 n=6)
GetTimeline_SQLite/events-100-4            175.4Ki ± 0%   175.4Ki ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4            846.1Ki ± 0%   846.1Ki ± 0%       ~ (p=0.182 n=6)
GetTimeline_SQLite/events-1000-4           1.639Mi ± 0%   1.639Mi ± 0%       ~ (p=0.567 n=6)
geomean                                    67.43Ki        67.42Ki       -0.03%
¹ all samples are equal

                                   │ baseline-bench.txt │        benchmark-results.txt        │
                                   │     allocs/op      │  allocs/op   vs base                │
EventStoreAppend_InMemory-4                  7.000 ± 0%    7.000 ± 0%       ~ (p=1.000 n=6) ¹
EventStoreAppend_SQLite-4                    53.00 ± 0%    53.00 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-10-4             125.0 ± 0%    125.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-50-4             653.0 ± 0%    653.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-100-4           1.306k ± 0%   1.306k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-500-4           6.514k ± 0%   6.514k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_InMemory/events-1000-4          13.02k ± 0%   13.02k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-10-4               382.0 ± 0%    382.0 ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-50-4              1.852k ± 0%   1.852k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-100-4             3.681k ± 0%   3.681k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-500-4             18.54k ± 0%   18.54k ± 0%       ~ (p=1.000 n=6) ¹
GetTimeline_SQLite/events-1000-4            37.29k ± 0%   37.29k ± 0%       ~ (p=1.000 n=6) ¹
geomean                                     1.162k        1.162k       +0.00%
¹ all samples are equal

Benchmarks run with go test -bench=. -benchmem -count=6.
Regressions ≥ 20% are flagged. Results compared via benchstat.

@intel352
Copy link
Contributor

@copilot apply changes based on the comments in this thread

- Remove brittle len(wrappers)==2 assertion; only check required keys exist
- Add key existence checks before calling wrappers["event"] and wrappers["eventbus"]
  to produce clear failures instead of nil-function panics
- Extend InlineEventBusTrigger test to verify flat config is wrapped into the
  EventBusTrigger native subscriptions format (workflow, action, topic fields)
- Add configCapturingTrigger helper to capture config passed to Configure()

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 12, 2026

@copilot apply changes based on the comments in this thread

Applied all review feedback in 5b410a7:

  • TestPipelineTriggerConfigWrappers: removed the brittle len(wrappers) == 2 assertion; now only checks that the required "event" and "eventbus" keys exist.
  • TestPipelineTriggerConfigWrapper_Event, TestPipelineTriggerConfigWrapper_EventBus, TestPipelineTriggerConfigWrapper_EventBus_WithEventFilter: each now captures the ok bool from the map lookup and calls t.Fatal if the key is missing, instead of potentially panicking on a nil function call.
  • TestPipeline_ConfigurePipelines_InlineEventBusTrigger: extended with a configCapturingTrigger helper (embeds mockTrigger + closure to record the received config) and explicitly registers the eventbus wrapper via engine.RegisterTriggerConfigWrapper. The test now asserts that capturedConfig contains the expected subscriptions[0].workflow == "pipeline:process-follow-up-event", action == "execute", and topic == "follow-up.created".

@intel352 intel352 merged commit 159a3d4 into main Mar 12, 2026
11 checks passed
@intel352 intel352 deleted the copilot/add-eventbus-trigger-pipeline branch March 12, 2026 16:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: EventBus-triggered pipeline execution

3 participants