Skip to content

fix(wfctl): imageRefForContainer resolves registry name to path#422

Merged
intel352 merged 1 commit intomainfrom
fix/build-imageref-registry-path
Apr 20, 2026
Merged

fix(wfctl): imageRefForContainer resolves registry name to path#422
intel352 merged 1 commit intomainfrom
fix/build-imageref-registry-path

Conversation

@intel352
Copy link
Copy Markdown
Contributor

Problem

imageRefForContainer in cmd/wfctl/build_image.go was using ctr.PushTo[0] (the registry name, e.g. docr) as the image ref prefix. This produced tags like docr/buymywishlist:sha, while the actual push target resolved to registry.digitalocean.com/bmw-registry/buymywishlist:sha. Docker push failed because the local image didn't exist under the push target name.

The symptom in BMW: images were built, retag + manual push was needed on every deploy.

Fix

  • Changed imageRefForContainer signature to accept registries []config.CIRegistry
  • Resolution now mirrors buildExternalImageRef: scan ci.registries[] for a Name match, use Path, fall back to raw name for backward compat
  • Threaded cfg.CI.Registries through buildWithDockerfile to the new signature

Test plan

  • TestImageRefForContainer_RegistryNameResolvesToPath — name match → uses path
  • TestImageRefForContainer_NoMatchFallback — no match → falls back to raw name
  • TestImageRefForContainer_EmptyPushTo — no push_to → returns name:tag
  • TestImageRefForContainer_MultiplePushTo — multiple push_to → first resolvable path used
  • TestRunBuildImage_ImageRefUsesRegistryPath — integration: dry-run output shows registry path, not registry name
  • All existing tests pass: GOWORK=off go test ./cmd/wfctl/...

🤖 Generated with Claude Code

imageRefForContainer was using ctr.PushTo[0] (the registry name, e.g.
"docr") as the image ref prefix. This caused images to be tagged as
"docr/buymywishlist:sha" but pushed to
"registry.digitalocean.com/bmw-registry/buymywishlist:sha", resulting
in push failures because the local tag didn't match the push target.

Fix mirrors buildExternalImageRef: scan ci.registries[] to resolve the
name to its path, falling back to the raw name for backward compat.
Also threads registries through buildWithDockerfile.
Copilot AI review requested due to automatic review settings April 20, 2026 19:09
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 build image Dockerfile builds to tag images using the configured registry path (from ci.registries[].path) when containers[].push_to references a registry name, matching the behavior already used for external image refs and preventing failed pushes due to mismatched local tags.

Changes:

  • Thread cfg.CI.Registries into Dockerfile builds and update imageRefForContainer to resolve push_to entries via ci.registries.
  • Add unit tests covering registry name→path resolution and fallback behaviors.
  • Add an integration-ish dry-run test asserting output uses the resolved registry path.

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 Passes CI registries into Dockerfile builds and resolves registry names to registry paths when constructing image refs.
cmd/wfctl/build_image_test.go Adds targeted tests for image ref construction and a dry-run assertion verifying resolved registry paths appear in output.

Comment thread cmd/wfctl/build_image.go
Comment on lines +241 to +245
func imageRefForContainer(ctr config.CIContainerTarget, tag string, registries []config.CIRegistry) string {
for _, regName := range ctr.PushTo {
for _, reg := range registries {
if reg.Name == regName {
return reg.Path + "/" + ctr.Name + ":" + tag
Comment thread cmd/wfctl/build_image.go
Comment on lines +241 to +246
func imageRefForContainer(ctr config.CIContainerTarget, tag string, registries []config.CIRegistry) string {
for _, regName := range ctr.PushTo {
for _, reg := range registries {
if reg.Name == regName {
return reg.Path + "/" + ctr.Name + ":" + tag
}
@github-actions
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:366690: parsing iteration count: invalid syntax
baseline-bench.txt:658720: parsing iteration count: invalid syntax
baseline-bench.txt:1011362: parsing iteration count: invalid syntax
baseline-bench.txt:1319808: parsing iteration count: invalid syntax
baseline-bench.txt:1666798: parsing iteration count: invalid syntax
benchmark-results.txt:245: parsing iteration count: invalid syntax
benchmark-results.txt:327063: parsing iteration count: invalid syntax
benchmark-results.txt:665689: parsing iteration count: invalid syntax
benchmark-results.txt:996911: parsing iteration count: invalid syntax
benchmark-results.txt:1299387: parsing iteration count: invalid syntax
benchmark-results.txt:1592230: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 7763 64-Core Processor                
                            │ benchmark-results.txt │
                            │        sec/op         │
InterpreterCreation-4                 3.284m ± 187%
ComponentLoad-4                       3.585m ±   1%
ComponentExecute-4                    1.929µ ±   1%
PoolContention/workers-1-4            1.080µ ±   1%
PoolContention/workers-2-4            1.081µ ±   2%
PoolContention/workers-4-4            1.081µ ±   1%
PoolContention/workers-8-4            1.084µ ±   1%
PoolContention/workers-16-4           1.089µ ±   0%
ComponentLifecycle-4                  3.609m ±   1%
SourceValidation-4                    2.248µ ±   1%
RegistryConcurrent-4                  794.4n ±   6%
LoaderLoadFromString-4                3.618m ±   1%
geomean                               17.43µ

                            │ 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

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                            │ baseline-bench.txt │
                            │       sec/op       │
InterpreterCreation-4               5.399m ± 96%
ComponentLoad-4                     3.499m ±  1%
ComponentExecute-4                  1.909µ ±  1%
PoolContention/workers-1-4          1.192µ ±  1%
PoolContention/workers-2-4          1.202µ ±  1%
PoolContention/workers-4-4          1.196µ ±  1%
PoolContention/workers-8-4          1.199µ ±  1%
PoolContention/workers-16-4         1.206µ ±  2%
ComponentLifecycle-4                3.569m ±  1%
SourceValidation-4                  2.309µ ±  1%
RegistryConcurrent-4                934.4n ±  8%
LoaderLoadFromString-4              3.659m ±  2%
geomean                             19.20µ

                            │ 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

pkg: github.com/GoCodeAlone/workflow/middleware
cpu: AMD EPYC 7763 64-Core Processor                
                                  │ benchmark-results.txt │
                                  │        sec/op         │
CircuitBreakerDetection-4                     284.7n ± 6%
CircuitBreakerExecution_Success-4             21.54n ± 0%
CircuitBreakerExecution_Failure-4             65.82n ± 1%
geomean                                       73.90n

                                  │ 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

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                  │ baseline-bench.txt │
                                  │       sec/op       │
CircuitBreakerDetection-4                  462.3n ± 0%
CircuitBreakerExecution_Success-4          59.71n ± 1%
CircuitBreakerExecution_Failure-4          65.42n ± 0%
geomean                                    121.8n

                                  │ 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

pkg: github.com/GoCodeAlone/workflow/module
cpu: AMD EPYC 7763 64-Core Processor                
                                 │ benchmark-results.txt │
                                 │        sec/op         │
JQTransform_Simple-4                        974.5n ± 15%
JQTransform_ObjectConstruction-4            1.432µ ±  0%
JQTransform_ArraySelect-4                   3.279µ ±  1%
JQTransform_Complex-4                       37.32µ ±  0%
JQTransform_Throughput-4                    1.760µ ±  0%
SSEPublishDelivery-4                        72.50n ±  1%
geomean                                     1.671µ

                                 │ 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

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                 │ baseline-bench.txt │
                                 │       sec/op       │
JQTransform_Simple-4                     949.7n ± 23%
JQTransform_ObjectConstruction-4         1.514µ ±  3%
JQTransform_ArraySelect-4                3.285µ ±  2%
JQTransform_Complex-4                    36.65µ ±  1%
JQTransform_Throughput-4                 1.823µ ±  2%
SSEPublishDelivery-4                     76.64n ±  9%
geomean                                  1.700µ

                                 │ 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

pkg: github.com/GoCodeAlone/workflow/schema
cpu: AMD EPYC 7763 64-Core Processor                
                                    │ benchmark-results.txt │
                                    │        sec/op         │
SchemaValidation_Simple-4                       1.103µ ± 8%
SchemaValidation_AllFields-4                    1.682µ ± 3%
SchemaValidation_FormatValidation-4             1.599µ ± 2%
SchemaValidation_ManySchemas-4                  1.808µ ± 3%
geomean                                         1.522µ

                                    │ 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

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                    │ baseline-bench.txt │
                                    │       sec/op       │
SchemaValidation_Simple-4                   1.010µ ± 21%
SchemaValidation_AllFields-4                1.499µ ±  1%
SchemaValidation_FormatValidation-4         1.462µ ±  4%
SchemaValidation_ManySchemas-4              1.485µ ±  4%
geomean                                     1.346µ

                                    │ 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

pkg: github.com/GoCodeAlone/workflow/store
cpu: AMD EPYC 7763 64-Core Processor                
                                   │ benchmark-results.txt │
                                   │        sec/op         │
EventStoreAppend_InMemory-4                   1.203µ ± 13%
EventStoreAppend_SQLite-4                     1.392m ±  7%
GetTimeline_InMemory/events-10-4              13.46µ ±  2%
GetTimeline_InMemory/events-50-4              76.24µ ±  2%
GetTimeline_InMemory/events-100-4             151.8µ ±  2%
GetTimeline_InMemory/events-500-4             615.5µ ± 11%
GetTimeline_InMemory/events-1000-4            1.261m ±  0%
GetTimeline_SQLite/events-10-4                106.2µ ±  1%
GetTimeline_SQLite/events-50-4                244.1µ ±  0%
GetTimeline_SQLite/events-100-4               410.8µ ±  1%
GetTimeline_SQLite/events-500-4               1.738m ±  1%
GetTimeline_SQLite/events-1000-4              3.398m ±  0%
geomean                                       219.8µ

                                   │ benchmark-results.txt │
                                   │         B/op          │
EventStoreAppend_InMemory-4                     807.0 ± 6%
EventStoreAppend_SQLite-4                     1.983Ki ± 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.46Ki

                                   │ 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

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                   │ baseline-bench.txt │
                                   │       sec/op       │
EventStoreAppend_InMemory-4                1.135µ ±  3%
EventStoreAppend_SQLite-4                  1.087m ±  3%
GetTimeline_InMemory/events-10-4           13.80µ ±  3%
GetTimeline_InMemory/events-50-4           75.61µ ±  2%
GetTimeline_InMemory/events-100-4          119.8µ ± 25%
GetTimeline_InMemory/events-500-4          611.4µ ±  1%
GetTimeline_InMemory/events-1000-4         1.238m ±  1%
GetTimeline_SQLite/events-10-4             84.03µ ±  1%
GetTimeline_SQLite/events-50-4             241.8µ ±  4%
GetTimeline_SQLite/events-100-4            438.4µ ±  2%
GetTimeline_SQLite/events-500-4            1.989m ±  2%
GetTimeline_SQLite/events-1000-4           3.862m ±  2%
geomean                                    211.4µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                 780.0 ± 10%
EventStoreAppend_SQLite-4                 1.985Ki ±  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.27Ki

                                   │ 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

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

@intel352 intel352 merged commit b189565 into main Apr 20, 2026
22 checks passed
@intel352 intel352 deleted the fix/build-imageref-registry-path branch April 20, 2026 19:21
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