fix(cli): prevent preview create from showing production route selector
resolvePreviewImageRef now resolves the registry directly from the first non-preview route without prompting. Also filter preview routes from the push command's route selector.
- commit
- 5418cc676ce251b8d4b702d4b07326c3b5816a25
- author
- brice · · 2026-03-18 18:09 UTC
- committer
- brice · · 2026-03-18 17:19 UTC
- parent
- cf696fb
- signature
- unsigned
1 file · +25 -2
M internal/adapters/in/cli/preview.go +25 -2
| @@ -232,9 +232,11 @@ func resolvePreviewImageRef(ctx context.Context, cp ControlPlane, out io.Writer, | |||
| 232 | 232 | return "", err | |
| 233 | 233 | } | |
| 234 | 234 | ||
| 235 | - | registry, _, _, err := resolveRoute(ctx, cp, "", "", dockerfile) | |
| 235 | + | // Resolve registry from existing routes without showing the interactive | |
| 236 | + | // selector — preview only needs the registry URL, not a target domain. | |
| 237 | + | registry, err := resolveRegistryForImage(ctx, cp, imageName) | |
| 236 | 238 | if err != nil { | |
| 237 | - | return "", fmt.Errorf("failed to resolve registry: %w", err) | |
| 239 | + | return "", err | |
| 238 | 240 | } | |
| 239 | 241 | ||
| 240 | 242 | previewRef := fmt.Sprintf("%s/%s:%s", registry, imageName, previewTag) | |
| @@ -244,6 +246,27 @@ func resolvePreviewImageRef(ctx context.Context, cp ControlPlane, out io.Writer, | |||
| 244 | 246 | return previewRef, nil | |
| 245 | 247 | } | |
| 246 | 248 | ||
| 249 | + | // resolveRegistryForImage finds the registry URL from any existing non-preview | |
| 250 | + | // route for the given image, without prompting. | |
| 251 | + | func resolveRegistryForImage(ctx context.Context, cp ControlPlane, imageName string) (string, error) { | |
| 252 | + | routes, err := cp.FindRoutesByImage(ctx, imageName) | |
| 253 | + | if err != nil { | |
| 254 | + | return "", fmt.Errorf("failed to find routes for image %q: %w", imageName, err) | |
| 255 | + | } | |
| 256 | + | ||
| 257 | + | for _, r := range routes { | |
| 258 | + | if strings.Contains(r.Domain, "--") { | |
| 259 | + | continue | |
| 260 | + | } | |
| 261 | + | reg, _, _ := parseImageRef(r.Image) | |
| 262 | + | if reg != "" { | |
| 263 | + | return reg, nil | |
| 264 | + | } | |
| 265 | + | } | |
| 266 | + | ||
| 267 | + | return "", fmt.Errorf("no route configured for image %q", imageName) | |
| 268 | + | } | |
| 269 | + | ||
| 247 | 270 | func buildAndPushPreview(ctx context.Context, out io.Writer, previewRef, previewTag, platform string, noBuild bool) error { | |
| 248 | 271 | imageOps, err := newImageOpsFn() | |
| 249 | 272 | if err != nil { | |
| @@ -232,9 +232,11 @@ func resolvePreviewImageRef(ctx context.Context, cp ControlPlane, out io.Writer, | |||||
| 232 | return "", err | 232 | return "", err | ||
| 233 | } | 233 | } | ||
| 234 | 234 | ||||
| 235 | - | registry, _, _, err := resolveRoute(ctx, cp, "", "", dockerfile) | 235 | + | // Resolve registry from existing routes without showing the interactive |
| 236 | + | // selector — preview only needs the registry URL, not a target domain. | |||
| 237 | + | registry, err := resolveRegistryForImage(ctx, cp, imageName) | |||
| 236 | if err != nil { | 238 | if err != nil { | ||
| 237 | - | return "", fmt.Errorf("failed to resolve registry: %w", err) | 239 | + | return "", err |
| 238 | } | 240 | } | ||
| 239 | 241 | ||||
| 240 | previewRef := fmt.Sprintf("%s/%s:%s", registry, imageName, previewTag) | 242 | previewRef := fmt.Sprintf("%s/%s:%s", registry, imageName, previewTag) | ||
| @@ -244,6 +246,27 @@ func resolvePreviewImageRef(ctx context.Context, cp ControlPlane, out io.Writer, | |||||
| 244 | return previewRef, nil | 246 | return previewRef, nil | ||
| 245 | } | 247 | } | ||
| 246 | 248 | ||||
| 249 | + | // resolveRegistryForImage finds the registry URL from any existing non-preview | |||
| 250 | + | // route for the given image, without prompting. | |||
| 251 | + | func resolveRegistryForImage(ctx context.Context, cp ControlPlane, imageName string) (string, error) { | |||
| 252 | + | routes, err := cp.FindRoutesByImage(ctx, imageName) | |||
| 253 | + | if err != nil { | |||
| 254 | + | return "", fmt.Errorf("failed to find routes for image %q: %w", imageName, err) | |||
| 255 | + | } | |||
| 256 | + | ||||
| 257 | + | for _, r := range routes { | |||
| 258 | + | if strings.Contains(r.Domain, "--") { | |||
| 259 | + | continue | |||
| 260 | + | } | |||
| 261 | + | reg, _, _ := parseImageRef(r.Image) | |||
| 262 | + | if reg != "" { | |||
| 263 | + | return reg, nil | |||
| 264 | + | } | |||
| 265 | + | } | |||
| 266 | + | ||||
| 267 | + | return "", fmt.Errorf("no route configured for image %q", imageName) | |||
| 268 | + | } | |||
| 269 | + | ||||
| 247 | func buildAndPushPreview(ctx context.Context, out io.Writer, previewRef, previewTag, platform string, noBuild bool) error { | 270 | func buildAndPushPreview(ctx context.Context, out io.Writer, previewRef, previewTag, platform string, noBuild bool) error { | ||
| 248 | imageOps, err := newImageOpsFn() | 271 | imageOps, err := newImageOpsFn() | ||
| 249 | if err != nil { | 272 | if err != nil { | ||