Skip to content

fix(wfctl): use docker buildx build in hardened mode#425

Merged
intel352 merged 1 commit into
mainfrom
fix/build-buildx-hardened
Apr 20, 2026
Merged

fix(wfctl): use docker buildx build in hardened mode#425
intel352 merged 1 commit into
mainfrom
fix/build-buildx-hardened

Conversation

@intel352

Copy link
Copy Markdown
Contributor

Problem

buildWithDockerfile appended --provenance=mode=max --sbom=true when ci.build.security.hardened=true but still called docker build. The classic docker driver rejects attestation flags with:

Attestation is not supported for the docker driver. Switch to a different driver, or turn on the containerd image store.

This was the root cause of the BMW CI failure that required a manual retag + push workaround.

Fix

  • When hardened=true: invoke docker buildx build (prepend buildx to args). The docker-container driver supports --provenance and --sbom.
  • When hardened=false: keep existing docker build behavior unchanged (backward compat).
  • Added a driver readiness check (docker buildx inspect --bootstrap) before the live hardened build. If it fails, returns a clear error: run 'docker buildx create --use' or add 'docker/setup-buildx-action@v3' to your CI workflow.
  • Dry-run output now correctly shows docker buildx build ... vs docker build ....

Test plan

  • TestRunBuildImage_HardenedUsesBuildx — hardened=true dry-run output contains docker buildx build
  • TestRunBuildImage_NonHardenedUsesPlainDocker — hardened=false dry-run output has docker build, no buildx
  • Existing TestRunBuildImage_HardenedProvenanceArgs — still passes (provenance/sbom flags present)
  • Existing TestRunBuildImage_NotHardenedNoProvenanceArgs — still passes (no provenance flags)
  • All tests: GOWORK=off go test ./cmd/wfctl/...

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings April 20, 2026 19:25
The classic docker build driver rejects --provenance and --sbom flags
with "Attestation is not supported for the docker driver." Only buildx
with the docker-container driver supports supply-chain attestation.

When hardened=true, prepend "buildx" to the docker args so the command
becomes "docker buildx build ...". Non-hardened builds keep plain
"docker build" for backward compat.

Also adds a driver readiness check (docker buildx inspect --bootstrap)
before the live hardened build with an actionable error message guiding
users to run "docker buildx create --use" or add setup-buildx-action@v3.
@intel352 intel352 force-pushed the fix/build-buildx-hardened branch from 7691d78 to 6d1c437 Compare April 20, 2026 19:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates wfctl container-image build behavior to support hardened builds with provenance/SBOM flags, and additionally introduces a new DigitalOcean deploy provider.

Changes:

  • Switch hardened Dockerfile builds to invoke docker buildx build and add a buildx “readiness” check before live hardened builds.
  • Add/extend tests to assert hardened vs non-hardened dry-run output (buildx build vs build).
  • Add a new digitalocean (do) deploy provider implementation plus unit tests.

Reviewed changes

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

File Description
cmd/wfctl/build_image.go Hardened builds use docker buildx build and run a preflight buildx inspect check.
cmd/wfctl/build_image_test.go Adds tests ensuring dry-run output reflects buildx usage when hardened.
cmd/wfctl/deploy_providers.go Registers and implements a new DigitalOcean deploy provider (create/update app, health check).
cmd/wfctl/deploy_providers_test.go Adds unit tests covering DigitalOcean provider behaviors.

Comment thread cmd/wfctl/build_image.go
// hardened mode uses buildx for provenance/SBOM attestation support.
var args []string
if hardened {
args = []string{"buildx", "build", "--file", dockerfile, "--tag", imageRef}

Copilot AI Apr 20, 2026

Copy link

Choose a reason for hiding this comment

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

In hardened mode this switches to docker buildx build, but no output mode is specified. With the recommended docker-container driver, buildx build does not load the image into the local Docker image store by default, which will break subsequent wfctl build push/docker push steps that expect the tagged image to exist locally. Consider adding an explicit output mode (e.g., load for single-platform builds or push when appropriate) and adjusting tests accordingly.

Suggested change
args = []string{"buildx", "build", "--file", dockerfile, "--tag", imageRef}
args = []string{"buildx", "build", "--file", dockerfile, "--tag", imageRef}
// With the recommended docker-container driver, buildx does not load
// the resulting image into the local Docker image store unless an
// explicit output mode is set. Preserve the non-hardened local-build
// behavior for builds that can be loaded into the daemon.
if len(ctr.Platforms) <= 1 {
args = append(args, "--load")
}

Copilot uses AI. Check for mistakes.
Comment thread cmd/wfctl/build_image.go
Comment on lines +166 to +172
if hardened {
// buildx with the docker-container driver is required for attestation flags.
// Verify a non-default builder is active; the default "docker" driver rejects --provenance.
if err := exec.Command("docker", "buildx", "inspect", "--bootstrap").Run(); err != nil {
return fmt.Errorf("hardened build requires docker buildx: run 'docker buildx create --use' " +
"or add 'docker/setup-buildx-action@v3' to your CI workflow (%w)", err)
}

Copilot AI Apr 20, 2026

Copy link

Choose a reason for hiding this comment

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

The buildx readiness check runs docker buildx inspect --bootstrap but doesn’t actually verify that the active builder is using a driver that supports attestations (the default "docker" driver can still inspect successfully, and the subsequent build will fail with the same attestation error). Consider checking the inspect output (or using a formatted inspect) to assert the driver is non-docker (e.g., docker-container), and include stderr/stdout in the returned error to make failures actionable.

Copilot uses AI. Check for mistakes.
@intel352 intel352 merged commit a4b77ab into main Apr 20, 2026
18 checks passed
@intel352 intel352 deleted the fix/build-buildx-hardened branch April 20, 2026 19:34
@github-actions

github-actions Bot commented Apr 20, 2026

Copy link
Copy Markdown

⏱ 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:299772: parsing iteration count: invalid syntax
baseline-bench.txt:623503: parsing iteration count: invalid syntax
baseline-bench.txt:951806: parsing iteration count: invalid syntax
baseline-bench.txt:1285542: parsing iteration count: invalid syntax
baseline-bench.txt:1561990: parsing iteration count: invalid syntax
benchmark-results.txt:245: parsing iteration count: invalid syntax
benchmark-results.txt:326448: parsing iteration count: invalid syntax
benchmark-results.txt:599665: parsing iteration count: invalid syntax
benchmark-results.txt:875636: parsing iteration count: invalid syntax
benchmark-results.txt:1150164: parsing iteration count: invalid syntax
benchmark-results.txt:1483402: 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              3.316m ± 190%   3.424m ± 186%       ~ (p=0.485 n=6)
ComponentLoad-4                    3.543m ±   1%   3.597m ±   1%  +1.51% (p=0.002 n=6)
ComponentExecute-4                 1.926µ ±   1%   1.923µ ±   2%       ~ (p=0.600 n=6)
PoolContention/workers-1-4         1.079µ ±   3%   1.082µ ±   0%       ~ (p=0.509 n=6)
PoolContention/workers-2-4         1.077µ ±   2%   1.083µ ±   2%       ~ (p=0.290 n=6)
PoolContention/workers-4-4         1.079µ ±   1%   1.094µ ±   2%       ~ (p=0.058 n=6)
PoolContention/workers-8-4         1.085µ ±   1%   1.090µ ±   1%       ~ (p=0.236 n=6)
PoolContention/workers-16-4        1.093µ ±   1%   1.089µ ±   2%       ~ (p=0.574 n=6)
ComponentLifecycle-4               3.591m ±   4%   3.630m ±   1%       ~ (p=0.093 n=6)
SourceValidation-4                 2.228µ ±   1%   2.233µ ±   1%       ~ (p=0.461 n=6)
RegistryConcurrent-4               781.5n ±   3%   791.2n ±   6%       ~ (p=0.180 n=6)
LoaderLoadFromString-4             3.581m ±   1%   3.644m ±   1%  +1.76% (p=0.002 n=6)
geomean                            17.37µ          17.53µ         +0.93%

                            │ baseline-bench.txt │        benchmark-results.txt         │
                            │        B/op        │     B/op      vs base                │
InterpreterCreation-4               2.027Mi ± 0%   2.027Mi ± 0%       ~ (p=0.853 n=6)
ComponentLoad-4                     2.180Mi ± 0%   2.180Mi ± 0%       ~ (p=0.221 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.183Mi ± 0%   2.183Mi ± 0%       ~ (p=0.104 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.182Mi ± 0%   2.182Mi ± 0%       ~ (p=0.071 n=6)
geomean                             15.25Ki        15.25Ki       +0.00%
¹ all samples are equal

                            │ baseline-bench.txt │        benchmark-results.txt        │
                            │     allocs/op      │  allocs/op   vs base                │
InterpreterCreation-4                15.68k ± 0%   15.68k ± 0%       ~ (p=1.000 n=6)
ComponentLoad-4                      18.02k ± 0%   18.02k ± 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                 18.07k ± 0%   18.07k ± 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               18.06k ± 0%   18.06k ± 0%       ~ (p=1.000 n=6) ¹
geomean                               183.3         183.3       +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                  283.2n ± 0%   283.9n ± 1%       ~ (p=0.589 n=6)
CircuitBreakerExecution_Success-4          21.53n ± 0%   21.55n ± 2%       ~ (p=0.165 n=6)
CircuitBreakerExecution_Failure-4          65.89n ± 2%   66.47n ± 1%       ~ (p=0.394 n=6)
geomean                                    73.79n        74.10n       +0.41%

                                  │ 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                     870.1n ± 26%   866.9n ± 30%       ~ (p=0.589 n=6)
JQTransform_ObjectConstruction-4         1.428µ ±  0%   1.447µ ±  1%  +1.37% (p=0.002 n=6)
JQTransform_ArraySelect-4                3.261µ ±  0%   3.323µ ±  1%  +1.90% (p=0.002 n=6)
JQTransform_Complex-4                    37.61µ ±  1%   38.02µ ±  1%  +1.09% (p=0.026 n=6)
JQTransform_Throughput-4                 1.755µ ±  1%   1.773µ ±  0%  +1.03% (p=0.009 n=6)
SSEPublishDelivery-4                     74.49n ±  1%   74.12n ±  1%       ~ (p=0.260 n=6)
geomean                                  1.646µ         1.659µ        +0.75%

                                 │ 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.141µ ± 5%   1.118µ ± 2%       ~ (p=0.310 n=6)
SchemaValidation_AllFields-4                 1.673µ ± 3%   1.656µ ± 4%       ~ (p=0.258 n=6)
SchemaValidation_FormatValidation-4          1.597µ ± 3%   1.598µ ± 2%       ~ (p=0.619 n=6)
SchemaValidation_ManySchemas-4               1.821µ ± 2%   1.811µ ± 3%       ~ (p=0.260 n=6)
geomean                                      1.535µ        1.521µ       -0.90%

                                    │ 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.216µ ±  8%   1.200µ ± 17%        ~ (p=0.937 n=6)
EventStoreAppend_SQLite-4                  1.413m ±  5%   1.923m ±  5%  +36.05% (p=0.002 n=6)
GetTimeline_InMemory/events-10-4           13.59µ ±  1%   14.27µ ±  3%   +5.00% (p=0.002 n=6)
GetTimeline_InMemory/events-50-4           75.15µ ± 13%   64.04µ ±  1%  -14.78% (p=0.002 n=6)
GetTimeline_InMemory/events-100-4          119.0µ ±  1%   128.5µ ±  1%   +7.94% (p=0.002 n=6)
GetTimeline_InMemory/events-500-4          611.8µ ±  0%   656.9µ ±  1%   +7.36% (p=0.002 n=6)
GetTimeline_InMemory/events-1000-4         1.252m ±  2%   1.353m ±  2%   +8.09% (p=0.002 n=6)
GetTimeline_SQLite/events-10-4             106.2µ ±  1%   119.9µ ±  1%  +12.94% (p=0.002 n=6)
GetTimeline_SQLite/events-50-4             244.3µ ±  0%   268.4µ ±  3%   +9.84% (p=0.002 n=6)
GetTimeline_SQLite/events-100-4            412.2µ ±  1%   439.1µ ±  1%   +6.53% (p=0.002 n=6)
GetTimeline_SQLite/events-500-4            1.769m ±  1%   1.844m ±  1%   +4.27% (p=0.002 n=6)
GetTimeline_SQLite/events-1000-4           3.437m ±  1%   3.582m ±  2%   +4.23% (p=0.002 n=6)
geomean                                    216.1µ         230.5µ         +6.64%

                                   │ baseline-bench.txt │        benchmark-results.txt         │
                                   │        B/op        │     B/op      vs base                │
EventStoreAppend_InMemory-4                  804.5 ± 7%     817.5 ± 9%       ~ (p=0.455 n=6)
EventStoreAppend_SQLite-4                  1.984Ki ± 1%   1.992Ki ± 2%       ~ (p=0.485 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.061 n=6)
GetTimeline_InMemory/events-1000-4         944.3Ki ± 0%   944.3Ki ± 0%  -0.00% (p=0.013 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%  +0.00% (p=0.013 n=6)
GetTimeline_SQLite/events-1000-4           1.639Mi ± 0%   1.639Mi ± 0%  -0.00% (p=0.006 n=6)
geomean                                    67.45Ki        67.56Ki       +0.17%
¹ 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.

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