Skip to content

fix(wfctl): pin plugin install to requested version, not stale manifest#426

Merged
intel352 merged 2 commits intomainfrom
fix/plugin-install-version-pin
Apr 20, 2026
Merged

fix(wfctl): pin plugin install to requested version, not stale manifest#426
intel352 merged 2 commits intomainfrom
fix/plugin-install-version-pin

Conversation

@intel352
Copy link
Copy Markdown
Contributor

Problem

When running wfctl plugin install workflow-plugin-payments@v0.2.1, the registry manifest may contain an older version (e.g. v0.1.0) with download URLs pointing at v0.1.0 assets. The requested version was silently ignored — v0.1.0 was installed instead.

BMW root cause: app.yaml declares requires.plugins: [{name: workflow-plugin-payments, version: v0.2.1}], but the registry manifest had v0.1.0. Every deploy installed v0.1.0.

Root cause

In runPluginInstall, parseNameVersion was called with _ discarding the version:

rawName, _ := parseNameVersion(nameArg)  // version thrown away

The manifest version from the registry then drove the download URL.

Fix

  • Capture requestedVersion from name@version
  • After FetchManifest, if requestedVersion != manifest.Version, call pinManifestToVersion to rewrite download URLs in-place: replaces /releases/download/v0.1.0/ with /releases/download/v0.2.1/, clears stale SHA256 checksums
  • On download failure, wraps the error with context: "requested version v0.2.1 not available for X (registry manifest is at v0.1.0)" — no silent fallback

Test plan

  • TestPinManifestToVersion_URLRewritten — unit: download URLs rewritten, SHA256 cleared, manifest.Version updated
  • TestPinManifestToVersion_SameVersion — unit: no-op when versions match
  • TestRunPluginInstall_VersionPinHitsNewURL — integration: fake registry serves v0.1.0 manifest; install request with @v0.2.1 hits v0.2.1 download URL and installs with v0.2.1 in plugin.json
  • TestRunPluginInstall_VersionPinNotFound — integration: v99.99.99 returns 404, error includes requested version
  • All existing tests pass: GOWORK=off go test ./cmd/wfctl/...

🤖 Generated with Claude Code

When running 'wfctl plugin install myplugin@v0.2.1', the registry
manifest may contain an older version (e.g. v0.1.0) with download URLs
pointing at v0.1.0 assets. The requested version was being silently
ignored, causing the old version to be installed.

Fix: capture the requested version from the name@version argument, and
when it differs from the manifest version, call pinManifestToVersion to
rewrite download URLs in-place (replaces /releases/download/v0.1.0/ with
/releases/download/v0.2.1/) and update manifest.Version. SHA256
checksums are cleared since they are only valid for the old assets.

If the rewritten URL returns a 404, the error is wrapped with context:
"requested version v0.2.1 not available for X (registry manifest is at
v0.1.0)" — no silent fallback to the stale version.

Root cause in BMW: app.yaml requires workflow-plugin-payments@v0.2.1 but
the registry manifest had v0.1.0, so deploys kept installing v0.1.0.
Copilot AI review requested due to automatic review settings April 20, 2026 19:41
Copy link
Copy Markdown
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

Fixes wfctl plugin install <name>@<version> so the requested version drives the download URL (even when the registry manifest is stale), preventing silent installs of an older version.

Changes:

  • Capture requestedVersion from name@version and pin the fetched registry manifest to that version before downloading.
  • Add pinManifestToVersion helper to rewrite download URLs and clear stale checksums.
  • Add unit + integration tests covering URL rewriting and failure behavior when the requested version doesn’t exist.

Reviewed changes

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

File Description
cmd/wfctl/plugin_install.go Uses requested @version to pin manifest URLs before install; adds pinManifestToVersion and improves error context on failures.
cmd/wfctl/plugin_version_pin_test.go Adds tests validating URL rewrite/no-op behavior and end-to-end install behavior with a stale manifest.


if err := installPluginFromManifest(pluginDirVal, pluginName, manifest); err != nil {
if requestedVersion != "" && requestedVersion != registryVersion {
return fmt.Errorf("requested version %s not available for %q (registry manifest is at %s): %w",
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

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

The wrapped error text says the requested version is “not available”, but installPluginFromManifest can fail for many other reasons (disk permissions, corrupt tarball, post-install verification, etc.). This message can be misleading; consider wording it as “failed to install requested version …” or only using the “not available” wording when the underlying failure is clearly a 404/missing asset.

Suggested change
return fmt.Errorf("requested version %s not available for %q (registry manifest is at %s): %w",
return fmt.Errorf("failed to install requested version %s for %q (registry manifest is at %s): %w",

Copilot uses AI. Check for mistakes.
Comment on lines +665 to +667
// If the version string also appears in the filename, rewrite that too.
if rewritten == url && oldVersion != "" {
rewritten = strings.ReplaceAll(url, oldVersion, requestedVersion)
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

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

pinManifestToVersion won’t rewrite version strings in the filename when the URL already matched the /releases/download/<old>/ pattern. For URLs like .../releases/download/v0.1.0/plugin-v0.1.0.tar.gz, the path gets updated but the filename remains at the old version, so the download can still 404 or fetch the wrong asset. Apply the second replacement against the already-rewritten URL (or check strings.Contains(rewritten, oldVersion)), not only when rewritten == url.

Suggested change
// If the version string also appears in the filename, rewrite that too.
if rewritten == url && oldVersion != "" {
rewritten = strings.ReplaceAll(url, oldVersion, requestedVersion)
// If the version string also appears elsewhere in the URL (for example,
// in the asset filename), rewrite that too using the already-updated URL.
if oldVersion != "" {
rewritten = strings.ReplaceAll(rewritten, oldVersion, requestedVersion)

Copilot uses AI. Check for mistakes.
// pinManifestToVersion rewrites download URLs in-place so the right release is fetched.
registryVersion := manifest.Version
if requestedVersion != "" && requestedVersion != manifest.Version {
pinManifestToVersion(manifest, requestedVersion)
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

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

When version pinning is active, all manifest SHA256 values are cleared, which means the download step will silently skip checksum verification for the pinned install. Consider emitting a clear warning (or failing unless a checksum for the requested version can be obtained) so users understand they’re installing without integrity verification in this path.

Suggested change
pinManifestToVersion(manifest, requestedVersion)
pinManifestToVersion(manifest, requestedVersion)
fmt.Fprintf(os.Stderr,
"warning: installing %q at requested version %s using a pinned manifest derived from registry version %s; checksum verification may be skipped for this install if no checksum is available for the requested version\n",
pluginName, requestedVersion, registryVersion,
)

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

github-actions Bot commented Apr 20, 2026

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:245: parsing iteration count: invalid syntax
baseline-bench.txt:300642: parsing iteration count: invalid syntax
baseline-bench.txt:620170: parsing iteration count: invalid syntax
baseline-bench.txt:915746: parsing iteration count: invalid syntax
baseline-bench.txt:1217925: parsing iteration count: invalid syntax
baseline-bench.txt:1488817: parsing iteration count: invalid syntax
benchmark-results.txt:245: parsing iteration count: invalid syntax
benchmark-results.txt:358347: parsing iteration count: invalid syntax
benchmark-results.txt:664648: parsing iteration count: invalid syntax
benchmark-results.txt:980150: parsing iteration count: invalid syntax
benchmark-results.txt:1253160: parsing iteration count: invalid syntax
benchmark-results.txt:1553950: 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 │
                            │       sec/op       │
InterpreterCreation-4              3.193m ± 199%
ComponentLoad-4                    3.611m ±  13%
ComponentExecute-4                 1.965µ ±   2%
PoolContention/workers-1-4         1.087µ ±   1%
PoolContention/workers-2-4         1.082µ ±   2%
PoolContention/workers-4-4         1.095µ ±   2%
PoolContention/workers-8-4         1.105µ ±   2%
PoolContention/workers-16-4        1.120µ ±   3%
ComponentLifecycle-4               3.691m ±   3%
SourceValidation-4                 2.333µ ±   2%
RegistryConcurrent-4               863.7n ±   4%
LoaderLoadFromString-4             3.727m ±   1%
geomean                            17.78µ

                            │ baseline-bench.txt │
                            │        B/op        │
InterpreterCreation-4               2.027Mi ± 0%
ComponentLoad-4                     2.180Mi ± 0%
ComponentExecute-4                  1.203Ki ± 0%
PoolContention/workers-1-4          1.203Ki ± 0%
PoolContention/workers-2-4          1.203Ki ± 0%
PoolContention/workers-4-4          1.203Ki ± 0%
PoolContention/workers-8-4          1.203Ki ± 0%
PoolContention/workers-16-4         1.203Ki ± 0%
ComponentLifecycle-4                2.183Mi ± 0%
SourceValidation-4                  1.984Ki ± 0%
RegistryConcurrent-4                1.133Ki ± 0%
LoaderLoadFromString-4              2.182Mi ± 0%
geomean                             15.25Ki

                            │ baseline-bench.txt │
                            │     allocs/op      │
InterpreterCreation-4                15.68k ± 0%
ComponentLoad-4                      18.02k ± 0%
ComponentExecute-4                    25.00 ± 0%
PoolContention/workers-1-4            25.00 ± 0%
PoolContention/workers-2-4            25.00 ± 0%
PoolContention/workers-4-4            25.00 ± 0%
PoolContention/workers-8-4            25.00 ± 0%
PoolContention/workers-16-4           25.00 ± 0%
ComponentLifecycle-4                 18.07k ± 0%
SourceValidation-4                    32.00 ± 0%
RegistryConcurrent-4                  2.000 ± 0%
LoaderLoadFromString-4               18.06k ± 0%
geomean                               183.3

cpu: AMD EPYC 9V74 80-Core Processor                
                            │ benchmark-results.txt │
                            │        sec/op         │
InterpreterCreation-4                 3.275m ± 182%
ComponentLoad-4                       3.499m ±   0%
ComponentExecute-4                    1.849µ ±   0%
PoolContention/workers-1-4            1.021µ ±   7%
PoolContention/workers-2-4            1.020µ ±   3%
PoolContention/workers-4-4            1.022µ ±   1%
PoolContention/workers-8-4            1.024µ ±   2%
PoolContention/workers-16-4           1.022µ ±   1%
ComponentLifecycle-4                  3.512m ±   1%
SourceValidation-4                    2.075µ ±   3%
RegistryConcurrent-4                  768.5n ±   4%
LoaderLoadFromString-4                3.535m ±   2%
geomean                               16.69µ

                            │ benchmark-results.txt │
                            │         B/op          │
InterpreterCreation-4                  2.027Mi ± 0%
ComponentLoad-4                        2.180Mi ± 0%
ComponentExecute-4                     1.203Ki ± 0%
PoolContention/workers-1-4             1.203Ki ± 0%
PoolContention/workers-2-4             1.203Ki ± 0%
PoolContention/workers-4-4             1.203Ki ± 0%
PoolContention/workers-8-4             1.203Ki ± 0%
PoolContention/workers-16-4            1.203Ki ± 0%
ComponentLifecycle-4                   2.183Mi ± 0%
SourceValidation-4                     1.984Ki ± 0%
RegistryConcurrent-4                   1.133Ki ± 0%
LoaderLoadFromString-4                 2.182Mi ± 0%
geomean                                15.25Ki

                            │ benchmark-results.txt │
                            │       allocs/op       │
InterpreterCreation-4                   15.68k ± 0%
ComponentLoad-4                         18.02k ± 0%
ComponentExecute-4                       25.00 ± 0%
PoolContention/workers-1-4               25.00 ± 0%
PoolContention/workers-2-4               25.00 ± 0%
PoolContention/workers-4-4               25.00 ± 0%
PoolContention/workers-8-4               25.00 ± 0%
PoolContention/workers-16-4              25.00 ± 0%
ComponentLifecycle-4                    18.07k ± 0%
SourceValidation-4                       32.00 ± 0%
RegistryConcurrent-4                     2.000 ± 0%
LoaderLoadFromString-4                  18.06k ± 0%
geomean                                  183.3

pkg: github.com/GoCodeAlone/workflow/middleware
cpu: AMD EPYC 7763 64-Core Processor                
                                  │ baseline-bench.txt │
                                  │       sec/op       │
CircuitBreakerDetection-4                  286.4n ± 8%
CircuitBreakerExecution_Success-4          21.57n ± 2%
CircuitBreakerExecution_Failure-4          66.23n ± 1%
geomean                                    74.24n

                                  │ baseline-bench.txt │
                                  │        B/op        │
CircuitBreakerDetection-4                 144.0 ± 0%
CircuitBreakerExecution_Success-4         0.000 ± 0%
CircuitBreakerExecution_Failure-4         0.000 ± 0%
geomean                                              ¹
¹ summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │
                                  │     allocs/op      │
CircuitBreakerDetection-4                 1.000 ± 0%
CircuitBreakerExecution_Success-4         0.000 ± 0%
CircuitBreakerExecution_Failure-4         0.000 ± 0%
geomean                                              ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                                  │ benchmark-results.txt │
                                  │        sec/op         │
CircuitBreakerDetection-4                     298.0n ± 5%
CircuitBreakerExecution_Success-4             22.67n ± 0%
CircuitBreakerExecution_Failure-4             70.92n ± 1%
geomean                                       78.25n

                                  │ benchmark-results.txt │
                                  │         B/op          │
CircuitBreakerDetection-4                    144.0 ± 0%
CircuitBreakerExecution_Success-4            0.000 ± 0%
CircuitBreakerExecution_Failure-4            0.000 ± 0%
geomean                                                 ¹
¹ summaries must be >0 to compute geomean

                                  │ benchmark-results.txt │
                                  │       allocs/op       │
CircuitBreakerDetection-4                    1.000 ± 0%
CircuitBreakerExecution_Success-4            0.000 ± 0%
CircuitBreakerExecution_Failure-4            0.000 ± 0%
geomean                                                 ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
cpu: AMD EPYC 7763 64-Core Processor                
                                 │ baseline-bench.txt │
                                 │       sec/op       │
JQTransform_Simple-4                     893.5n ± 26%
JQTransform_ObjectConstruction-4         1.478µ ±  2%
JQTransform_ArraySelect-4                3.434µ ±  2%
JQTransform_Complex-4                    38.51µ ±  1%
JQTransform_Throughput-4                 1.822µ ±  1%
SSEPublishDelivery-4                     72.27n ±  0%
geomean                                  1.686µ

                                 │ baseline-bench.txt │
                                 │        B/op        │
JQTransform_Simple-4                   1.273Ki ± 0%
JQTransform_ObjectConstruction-4       1.773Ki ± 0%
JQTransform_ArraySelect-4              2.625Ki ± 0%
JQTransform_Complex-4                  16.22Ki ± 0%
JQTransform_Throughput-4               1.984Ki ± 0%
SSEPublishDelivery-4                     0.000 ± 0%
geomean                                             ¹
¹ summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │
                                 │     allocs/op      │
JQTransform_Simple-4                     10.00 ± 0%
JQTransform_ObjectConstruction-4         15.00 ± 0%
JQTransform_ArraySelect-4                30.00 ± 0%
JQTransform_Complex-4                    324.0 ± 0%
JQTransform_Throughput-4                 17.00 ± 0%
SSEPublishDelivery-4                     0.000 ± 0%
geomean                                             ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                                 │ benchmark-results.txt │
                                 │        sec/op         │
JQTransform_Simple-4                        819.5n ± 28%
JQTransform_ObjectConstruction-4            1.382µ ± 17%
JQTransform_ArraySelect-4                   3.326µ ±  1%
JQTransform_Complex-4                       40.59µ ±  1%
JQTransform_Throughput-4                    1.712µ ±  1%
SSEPublishDelivery-4                        65.34n ±  2%
geomean                                     1.605µ

                                 │ benchmark-results.txt │
                                 │         B/op          │
JQTransform_Simple-4                      1.273Ki ± 0%
JQTransform_ObjectConstruction-4          1.773Ki ± 0%
JQTransform_ArraySelect-4                 2.625Ki ± 0%
JQTransform_Complex-4                     16.22Ki ± 0%
JQTransform_Throughput-4                  1.984Ki ± 0%
SSEPublishDelivery-4                        0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

                                 │ benchmark-results.txt │
                                 │       allocs/op       │
JQTransform_Simple-4                        10.00 ± 0%
JQTransform_ObjectConstruction-4            15.00 ± 0%
JQTransform_ArraySelect-4                   30.00 ± 0%
JQTransform_Complex-4                       324.0 ± 0%
JQTransform_Throughput-4                    17.00 ± 0%
SSEPublishDelivery-4                        0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
cpu: AMD EPYC 7763 64-Core Processor                
                                    │ baseline-bench.txt │
                                    │       sec/op       │
SchemaValidation_Simple-4                    1.106µ ± 6%
SchemaValidation_AllFields-4                 1.671µ ± 1%
SchemaValidation_FormatValidation-4          1.597µ ± 2%
SchemaValidation_ManySchemas-4               1.812µ ± 1%
geomean                                      1.520µ

                                    │ baseline-bench.txt │
                                    │        B/op        │
SchemaValidation_Simple-4                   0.000 ± 0%
SchemaValidation_AllFields-4                0.000 ± 0%
SchemaValidation_FormatValidation-4         0.000 ± 0%
SchemaValidation_ManySchemas-4              0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │
                                    │     allocs/op      │
SchemaValidation_Simple-4                   0.000 ± 0%
SchemaValidation_AllFields-4                0.000 ± 0%
SchemaValidation_FormatValidation-4         0.000 ± 0%
SchemaValidation_ManySchemas-4              0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                                    │ benchmark-results.txt │
                                    │        sec/op         │
SchemaValidation_Simple-4                       1.066µ ± 3%
SchemaValidation_AllFields-4                    1.616µ ± 2%
SchemaValidation_FormatValidation-4             1.552µ ± 1%
SchemaValidation_ManySchemas-4                  1.591µ ± 2%
geomean                                         1.436µ

                                    │ benchmark-results.txt │
                                    │         B/op          │
SchemaValidation_Simple-4                      0.000 ± 0%
SchemaValidation_AllFields-4                   0.000 ± 0%
SchemaValidation_FormatValidation-4            0.000 ± 0%
SchemaValidation_ManySchemas-4                 0.000 ± 0%
geomean                                                   ¹
¹ summaries must be >0 to compute geomean

                                    │ benchmark-results.txt │
                                    │       allocs/op       │
SchemaValidation_Simple-4                      0.000 ± 0%
SchemaValidation_AllFields-4                   0.000 ± 0%
SchemaValidation_FormatValidation-4            0.000 ± 0%
SchemaValidation_ManySchemas-4                 0.000 ± 0%
geomean                                                   ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
cpu: AMD EPYC 7763 64-Core Processor                
                                   │ baseline-bench.txt │
                                   │       sec/op       │
EventStoreAppend_InMemory-4                1.106µ ± 24%
EventStoreAppend_SQLite-4                  1.340m ± 11%
GetTimeline_InMemory/events-10-4           13.86µ ±  6%
GetTimeline_InMemory/events-50-4           77.55µ ±  3%
GetTimeline_InMemory/events-100-4          122.6µ ±  1%
GetTimeline_InMemory/events-500-4          627.5µ ±  1%
GetTimeline_InMemory/events-1000-4         1.289m ±  1%
GetTimeline_SQLite/events-10-4             107.3µ ±  1%
GetTimeline_SQLite/events-50-4             247.1µ ±  1%
GetTimeline_SQLite/events-100-4            418.3µ ±  1%
GetTimeline_SQLite/events-500-4            1.768m ±  1%
GetTimeline_SQLite/events-1000-4           3.445m ±  0%
geomean                                    216.6µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                 780.0 ± 11%
EventStoreAppend_SQLite-4                 1.987Ki ±  1%
GetTimeline_InMemory/events-10-4          7.953Ki ±  0%
GetTimeline_InMemory/events-50-4          46.62Ki ±  0%
GetTimeline_InMemory/events-100-4         94.48Ki ±  0%
GetTimeline_InMemory/events-500-4         472.8Ki ±  0%
GetTimeline_InMemory/events-1000-4        944.3Ki ±  0%
GetTimeline_SQLite/events-10-4            16.74Ki ±  0%
GetTimeline_SQLite/events-50-4            87.14Ki ±  0%
GetTimeline_SQLite/events-100-4           175.4Ki ±  0%
GetTimeline_SQLite/events-500-4           846.1Ki ±  0%
GetTimeline_SQLite/events-1000-4          1.639Mi ±  0%
geomean                                   67.28Ki

                                   │ baseline-bench.txt │
                                   │     allocs/op      │
EventStoreAppend_InMemory-4                  7.000 ± 0%
EventStoreAppend_SQLite-4                    53.00 ± 0%
GetTimeline_InMemory/events-10-4             125.0 ± 0%
GetTimeline_InMemory/events-50-4             653.0 ± 0%
GetTimeline_InMemory/events-100-4           1.306k ± 0%
GetTimeline_InMemory/events-500-4           6.514k ± 0%
GetTimeline_InMemory/events-1000-4          13.02k ± 0%
GetTimeline_SQLite/events-10-4               382.0 ± 0%
GetTimeline_SQLite/events-50-4              1.852k ± 0%
GetTimeline_SQLite/events-100-4             3.681k ± 0%
GetTimeline_SQLite/events-500-4             18.54k ± 0%
GetTimeline_SQLite/events-1000-4            37.29k ± 0%
geomean                                     1.162k

cpu: AMD EPYC 9V74 80-Core Processor                
                                   │ benchmark-results.txt │
                                   │        sec/op         │
EventStoreAppend_InMemory-4                   1.151µ ± 18%
EventStoreAppend_SQLite-4                     1.062m ±  5%
GetTimeline_InMemory/events-10-4              13.54µ ±  5%
GetTimeline_InMemory/events-50-4              70.03µ ± 18%
GetTimeline_InMemory/events-100-4             116.4µ ±  3%
GetTimeline_InMemory/events-500-4             592.2µ ±  1%
GetTimeline_InMemory/events-1000-4            1.202m ±  1%
GetTimeline_SQLite/events-10-4                86.72µ ±  3%
GetTimeline_SQLite/events-50-4                230.9µ ±  1%
GetTimeline_SQLite/events-100-4               402.9µ ±  0%
GetTimeline_SQLite/events-500-4               1.735m ±  1%
GetTimeline_SQLite/events-1000-4              3.418m ±  3%
geomean                                       201.9µ

                                   │ benchmark-results.txt │
                                   │         B/op          │
EventStoreAppend_InMemory-4                     808.5 ± 8%
EventStoreAppend_SQLite-4                     1.982Ki ± 2%
GetTimeline_InMemory/events-10-4              7.953Ki ± 0%
GetTimeline_InMemory/events-50-4              46.62Ki ± 0%
GetTimeline_InMemory/events-100-4             94.48Ki ± 0%
GetTimeline_InMemory/events-500-4             472.8Ki ± 0%
GetTimeline_InMemory/events-1000-4            944.3Ki ± 0%
GetTimeline_SQLite/events-10-4                16.74Ki ± 0%
GetTimeline_SQLite/events-50-4                87.14Ki ± 0%
GetTimeline_SQLite/events-100-4               175.4Ki ± 0%
GetTimeline_SQLite/events-500-4               846.1Ki ± 0%
GetTimeline_SQLite/events-1000-4              1.639Mi ± 0%
geomean                                       67.47Ki

                                   │ benchmark-results.txt │
                                   │       allocs/op       │
EventStoreAppend_InMemory-4                     7.000 ± 0%
EventStoreAppend_SQLite-4                       53.00 ± 0%
GetTimeline_InMemory/events-10-4                125.0 ± 0%
GetTimeline_InMemory/events-50-4                653.0 ± 0%
GetTimeline_InMemory/events-100-4              1.306k ± 0%
GetTimeline_InMemory/events-500-4              6.514k ± 0%
GetTimeline_InMemory/events-1000-4             13.02k ± 0%
GetTimeline_SQLite/events-10-4                  382.0 ± 0%
GetTimeline_SQLite/events-50-4                 1.852k ± 0%
GetTimeline_SQLite/events-100-4                3.681k ± 0%
GetTimeline_SQLite/events-500-4                18.54k ± 0%
GetTimeline_SQLite/events-1000-4               37.29k ± 0%
geomean                                        1.162k

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

@intel352 intel352 merged commit 0dbf8b6 into main Apr 20, 2026
18 checks passed
@intel352 intel352 deleted the fix/plugin-install-version-pin branch April 20, 2026 19:54
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.

2 participants