Skip to content

fix: preserve wfctl release version#750

Merged
intel352 merged 2 commits into
mainfrom
codex/wfctl-version-linker-fix
May 21, 2026
Merged

fix: preserve wfctl release version#750
intel352 merged 2 commits into
mainfrom
codex/wfctl-version-linker-fix

Conversation

@intel352
Copy link
Copy Markdown
Contributor

Summary

  • Make the wfctl version variable linker-overridable by release -ldflags -X main.version=... builds, with build metadata fallback for dev/module installs.
  • Add a regression test that builds wfctl with -X main.version=v9.9.9 and verifies wfctl --version reports that exact tag.
  • Notify workflow-registry after non-prerelease workflow releases so registry core manifests and README indexes can refresh.

Adversarial review

  • Verified the root cause: linker -X cannot override a string variable initialized from buildVersion(); the new initializer is a plain string and fallback runs in init.
  • Checked that release notification uses the existing repo_dispatch_token pattern and only runs after release for non-prerelease tags.
  • actionlint .github/workflows/release.yml reports pre-existing shellcheck warnings at release.yml lines 145 and 287; the new registry notification block is not implicated.

Test Plan

  • GOWORK=off go test ./cmd/wfctl -run 'Test(BuildVersionStripsDirtyMarker|LinkedVersionOverridesBuildInfo|RunUpdate_CheckOnly|RunUpdate_AlreadyLatest|CheckForUpdateNotice_SkipsDevBuild)' -count=1 -v
  • git diff --check

Copilot AI review requested due to automatic review settings May 21, 2026 06:01
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

This PR fixes wfctl version reporting so release builds can reliably inject the release tag via linker -ldflags -X main.version=..., while still deriving a useful version from Go build metadata for module-installed/dev builds. It also adds automation to notify workflow-registry after stable (non-prerelease) workflow releases.

Changes:

  • Make cmd/wfctl’s version variable linker-overridable and move build-metadata fallback into init().
  • Add a regression test that builds wfctl with -X main.version=... and asserts wfctl --version matches.
  • Add a release workflow job to repository-dispatch workflow-registry after non-prerelease releases.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
cmd/wfctl/main.go Switches version to a constant initializer ("dev") so -X main.version=... works; falls back to debug.ReadBuildInfo() in init().
cmd/wfctl/main_test.go Adds regression coverage that builds a wfctl binary with -ldflags -X main.version=... and verifies --version output.
.github/workflows/release.yml Adds a post-release repository-dispatch notification to GoCodeAlone/workflow-registry for stable tags.

Comment thread cmd/wfctl/main_test.go
@codecov
Copy link
Copy Markdown

codecov Bot commented May 21, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 21, 2026

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:276: parsing iteration count: invalid syntax
baseline-bench.txt:323977: parsing iteration count: invalid syntax
baseline-bench.txt:589607: parsing iteration count: invalid syntax
baseline-bench.txt:854181: parsing iteration count: invalid syntax
baseline-bench.txt:1138798: parsing iteration count: invalid syntax
baseline-bench.txt:1398890: parsing iteration count: invalid syntax
benchmark-results.txt:276: parsing iteration count: invalid syntax
benchmark-results.txt:536089: parsing iteration count: invalid syntax
benchmark-results.txt:854900: parsing iteration count: invalid syntax
benchmark-results.txt:1182549: parsing iteration count: invalid syntax
benchmark-results.txt:1461094: parsing iteration count: invalid syntax
benchmark-results.txt:1799600: 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               7.454m ± 58%   6.851m ± 60%       ~ (p=0.485 n=6)
ComponentLoad-4                     3.694m ±  9%   3.546m ±  7%       ~ (p=0.132 n=6)
ComponentExecute-4                  1.986µ ±  2%   1.894µ ±  1%  -4.63% (p=0.002 n=6)
PoolContention/workers-1-4          1.118µ ±  3%   1.066µ ±  2%  -4.65% (p=0.002 n=6)
PoolContention/workers-2-4          1.108µ ±  2%   1.063µ ±  1%  -4.06% (p=0.002 n=6)
PoolContention/workers-4-4          1.132µ ±  1%   1.069µ ±  1%  -5.57% (p=0.002 n=6)
PoolContention/workers-8-4          1.129µ ±  1%   1.072µ ±  0%  -5.01% (p=0.002 n=6)
PoolContention/workers-16-4         1.123µ ±  2%   1.073µ ±  3%  -4.45% (p=0.002 n=6)
ComponentLifecycle-4                3.793m ±  3%   3.537m ±  0%  -6.75% (p=0.002 n=6)
SourceValidation-4                  2.393µ ±  1%   2.278µ ±  1%  -4.83% (p=0.002 n=6)
RegistryConcurrent-4                796.7n ±  3%   773.0n ±  5%  -2.97% (p=0.041 n=6)
LoaderLoadFromString-4              3.803m ±  4%   3.552m ±  1%  -6.58% (p=0.002 n=6)
geomean                             19.30µ         18.31µ        -5.14%

                            │ baseline-bench.txt │        benchmark-results.txt         │
                            │        B/op        │     B/op      vs base                │
InterpreterCreation-4               2.027Mi ± 0%   2.027Mi ± 0%       ~ (p=0.701 n=6)
ComponentLoad-4                     2.180Mi ± 0%   2.180Mi ± 0%       ~ (p=0.916 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.844 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.853 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                  289.8n ± 5%   282.9n ± 6%  -2.36% (p=0.039 n=6)
CircuitBreakerExecution_Success-4          21.42n ± 0%   21.43n ± 0%       ~ (p=0.377 n=6)
CircuitBreakerExecution_Failure-4          66.19n ± 0%   66.64n ± 0%  +0.69% (p=0.002 n=6)
geomean                                    74.34n        73.93n       -0.55%

                                  │ 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              │
IaCStateBackend_InProcess-4              322.8n ±  1%   317.4n ± 17%       ~ (p=0.065 n=6)
IaCStateBackend_GRPC-4                   9.714m ± 20%   9.392m ± 16%  -3.31% (p=0.041 n=6)
JQTransform_Simple-4                     705.7n ± 44%   651.2n ± 38%       ~ (p=0.180 n=6)
JQTransform_ObjectConstruction-4         1.643µ ±  1%   1.493µ ±  1%  -9.13% (p=0.002 n=6)
JQTransform_ArraySelect-4                3.698µ ±  2%   3.395µ ±  0%  -8.19% (p=0.002 n=6)
JQTransform_Complex-4                    40.94µ ±  1%   38.55µ ±  0%  -5.84% (p=0.002 n=6)
JQTransform_Throughput-4                 2.014µ ±  3%   1.825µ ±  0%  -9.41% (p=0.002 n=6)
SSEPublishDelivery-4                     64.72n ±  1%   65.27n ±  4%       ~ (p=0.093 n=6)
geomean                                  4.045µ         3.818µ        -5.62%

                                 │ baseline-bench.txt │         benchmark-results.txt         │
                                 │        B/op        │     B/op       vs base                │
IaCStateBackend_InProcess-4             416.0 ±  0%       416.0 ±  0%       ~ (p=1.000 n=6) ¹
IaCStateBackend_GRPC-4                5.823Mi ± 10%     5.924Mi ± 10%       ~ (p=0.589 n=6)
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.22%               ²
¹ all samples are equal
² summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │        benchmark-results.txt        │
                                 │     allocs/op      │  allocs/op   vs base                │
IaCStateBackend_InProcess-4              2.000 ± 0%      2.000 ± 0%       ~ (p=1.000 n=6) ¹
IaCStateBackend_GRPC-4                  6.838k ± 0%     6.834k ± 0%       ~ (p=0.420 n=6)
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.01%               ²
¹ 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.101µ ±  2%   1.099µ ±  2%       ~ (p=0.900 n=6)
SchemaValidation_AllFields-4                1.668µ ± 13%   1.662µ ±  8%       ~ (p=0.781 n=6)
SchemaValidation_FormatValidation-4         1.601µ ±  2%   1.581µ ±  1%       ~ (p=0.132 n=6)
SchemaValidation_ManySchemas-4              1.855µ ±  3%   1.791µ ± 20%       ~ (p=0.058 n=6)
geomean                                     1.528µ         1.508µ        -1.29%

                                    │ 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.203µ ± 26%   1.317µ ± 22%        ~ (p=0.937 n=6)
EventStoreAppend_SQLite-4                  1.339m ±  4%   1.743m ± 17%  +30.18% (p=0.002 n=6)
GetTimeline_InMemory/events-10-4           13.98µ ±  2%   14.18µ ±  3%        ~ (p=0.310 n=6)
GetTimeline_InMemory/events-50-4           63.15µ ± 28%   79.00µ ±  3%  +25.09% (p=0.041 n=6)
GetTimeline_InMemory/events-100-4          126.1µ ±  1%   152.9µ ± 16%  +21.23% (p=0.002 n=6)
GetTimeline_InMemory/events-500-4          648.4µ ±  1%   656.5µ ±  2%        ~ (p=0.093 n=6)
GetTimeline_InMemory/events-1000-4         1.329m ±  1%   1.359m ±  1%   +2.28% (p=0.002 n=6)
GetTimeline_SQLite/events-10-4             110.5µ ±  1%   108.7µ ±  0%   -1.55% (p=0.002 n=6)
GetTimeline_SQLite/events-50-4             257.8µ ±  1%   256.4µ ±  2%        ~ (p=0.180 n=6)
GetTimeline_SQLite/events-100-4            438.4µ ±  1%   434.2µ ±  1%        ~ (p=0.065 n=6)
GetTimeline_SQLite/events-500-4            1.836m ±  2%   1.838m ±  0%        ~ (p=0.818 n=6)
GetTimeline_SQLite/events-1000-4           3.581m ±  2%   3.576m ±  1%        ~ (p=1.000 n=6)
geomean                                    219.8µ         234.7µ         +6.79%

                                   │ baseline-bench.txt │        benchmark-results.txt         │
                                   │        B/op        │     B/op      vs base                │
EventStoreAppend_InMemory-4                 843.0 ± 12%     829.5 ± 9%       ~ (p=0.699 n=6)
EventStoreAppend_SQLite-4                 1.984Ki ±  2%   1.986Ki ± 2%       ~ (p=1.000 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.242 n=6)
GetTimeline_InMemory/events-1000-4        944.3Ki ±  0%   944.3Ki ± 0%       ~ (p=0.152 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.074 n=6)
GetTimeline_SQLite/events-1000-4          1.639Mi ±  0%   1.639Mi ± 0%  -0.00% (p=0.004 n=6)
geomean                                   67.71Ki         67.62Ki       -0.13%
¹ 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 intel352 merged commit 944f380 into main May 21, 2026
22 checks passed
@intel352 intel352 deleted the codex/wfctl-version-linker-fix branch May 21, 2026 06:27
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