Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package kpt-cli for openSUSE:Factory checked in at 2026-07-14 13:50:48 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kpt-cli (Old) and /work/SRC/openSUSE:Factory/.kpt-cli.new.1991 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kpt-cli" Tue Jul 14 13:50:48 2026 rev:6 rq:1365471 version:1.0.0~beta.67 Changes: -------- --- /work/SRC/openSUSE:Factory/kpt-cli/kpt-cli.changes 2026-07-09 22:22:15.960036115 +0200 +++ /work/SRC/openSUSE:Factory/.kpt-cli.new.1991/kpt-cli.changes 2026-07-14 13:51:16.793764754 +0200 @@ -1,0 +2,31 @@ +Tue Jul 14 05:08:12 UTC 2026 - Johannes Kastl <[email protected]> + +- Update to version 1.0.0~beta.67: + * Bump SDK (#4635) + * Build arm64 images, add CI check for goreleaser validity + (#4634) + * Refactor gh action worklfows (#4631) + * Fix go-releaser, migrate away from deprecations (#4630) + * docs: document configurable image prefix via flag and env var + (#4617) + * Make the image prefix configurable (#4616) + * Bump golang.org/x/net from 0.54.0 to 0.55.0 in /healthcheck + (#4618) + * Use API v0.0.2 and SDK v1.1.0 (#4620) + * Linking container images to releases and remove gcloud image + build (#4628) + * Fix broken download links + +------------------------------------------------------------------- +Mon Jul 13 12:01:38 UTC 2026 - Johannes Kastl <[email protected]> + +- Update to version 1.0.0~beta.66.1: + * Refactor gh action worklfows (#4631) + * Fix go-releaser, migrate away from deprecations (#4630) + * docs: document configurable image prefix via flag and env var + (#4617) + * Make the image prefix configurable (#4616) + * Bump golang.org/x/net from 0.54.0 to 0.55.0 in /healthcheck + (#4618) + +------------------------------------------------------------------- Old: ---- kpt-cli-1.0.0~beta.66.obscpio New: ---- kpt-cli-1.0.0~beta.67.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kpt-cli.spec ++++++ --- /var/tmp/diff_new_pack.8xi92S/_old 2026-07-14 13:51:21.425923195 +0200 +++ /var/tmp/diff_new_pack.8xi92S/_new 2026-07-14 13:51:21.441923743 +0200 @@ -20,7 +20,7 @@ %define executable_name kpt Name: kpt-cli -Version: 1.0.0~beta.66 +Version: 1.0.0~beta.67 Release: 0 Summary: CLI for kpt - automate Kubernetes Configuration Editing License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.8xi92S/_old 2026-07-14 13:51:21.821936741 +0200 +++ /var/tmp/diff_new_pack.8xi92S/_new 2026-07-14 13:51:21.865938246 +0200 @@ -1,9 +1,9 @@ <services> <service name="obs_scm" mode="manual"> - <param name="url">https://github.com/kptdev/kpt</param> + <param name="url">https://github.com/kptdev/kpt.git</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v1.0.0-beta.66</param> + <param name="revision">refs/tags/v1.0.0-beta.67</param> <param name="versionformat">@PARENT_TAG@</param> <param name="changesgenerate">enable</param> <param name="versionrewrite-pattern">v(.*)-(beta\.*)</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.8xi92S/_old 2026-07-14 13:51:22.061944951 +0200 +++ /var/tmp/diff_new_pack.8xi92S/_new 2026-07-14 13:51:22.101946319 +0200 @@ -1,6 +1,8 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/kptdev/kpt</param> - <param name="changesrevision">30c074ce1f9ab17958207ada884564ccc2cc5d13</param></service></servicedata> + <param name="changesrevision">8863dda97a936fba40af1759d877022a6b73a65c</param></service><service name="tar_scm"> + <param name="url">https://github.com/kptdev/kpt.git</param> + <param name="changesrevision">6bfa2af14026843300e6b3289cb6f78e2bc8be47</param></service></servicedata> (No newline at EOF) ++++++ kpt-cli-1.0.0~beta.66.obscpio -> kpt-cli-1.0.0~beta.67.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/api/schema/v1/group_version.go new/kpt-cli-1.0.0~beta.67/api/schema/v1/group_version.go --- old/kpt-cli-1.0.0~beta.66/api/schema/v1/group_version.go 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/api/schema/v1/group_version.go 2026-07-13 15:16:28.000000000 +0200 @@ -49,12 +49,12 @@ // ParseGroupKind turns "Kind.group" string into a GroupKind struct. func ParseGroupKind(gk string) GroupKind { - i := strings.Index(gk, ".") - if i == -1 { + before, after, ok := strings.Cut(gk, ".") + if !ok { return GroupKind{Kind: gk} } - return GroupKind{Group: gk[i+1:], Kind: gk[:i]} + return GroupKind{Group: after, Kind: before} } // GroupVersionKind unambiguously identifies a kind. It doesn't anonymously include GroupVersion diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/commands/fn/doc/cmdfndoc.go new/kpt-cli-1.0.0~beta.67/commands/fn/doc/cmdfndoc.go --- old/kpt-cli-1.0.0~beta.66/commands/fn/doc/cmdfndoc.go 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/commands/fn/doc/cmdfndoc.go 2026-07-13 15:16:28.000000000 +0200 @@ -32,10 +32,11 @@ func NewRunner(ctx context.Context, parent string) *Runner { r := &Runner{ - Ctx: ctx, + Ctx: ctx, + RunnerOptions: runneroptions.RunnerOptions{}, } c := &cobra.Command{ - Use: "doc --image=IMAGE", + Use: "doc --image=IMAGE [--image-prefix=PREFIX]", Args: cobra.MaximumNArgs(0), Short: fndocs.DocShort, Long: fndocs.DocShort + "\n" + fndocs.DocLong, @@ -44,6 +45,8 @@ } r.Command = c c.Flags().StringVarP(&r.Image, "image", "i", "", "kpt function image name") + c.Flags().StringVar(&r.RunnerOptions.ImagePrefix, "image-prefix", runneroptions.DefaultImagePrefix(), + fmt.Sprintf("The prefix used when converting from short path to the full URL (defaults to $%s if set)", runneroptions.PrefixEnvVar)) cmdutil.FixDocs("kpt", parent, c) return r } @@ -53,17 +56,21 @@ } type Runner struct { - Image string - Command *cobra.Command - Ctx context.Context + Image string + RunnerOptions runneroptions.RunnerOptions + Command *cobra.Command + Ctx context.Context } func (r *Runner) runE(_ *cobra.Command, _ []string) error { + if err := r.RunnerOptions.ValidatePrefix(); err != nil { + return err + } if r.Image == "" { return errors.New("image must be specified") } - resolveFunc := runneroptions.ResolveToImageForCLIFunc(runneroptions.GHCRImagePrefix) - image := resolveFunc(r.Image) + + image := r.RunnerOptions.ResolveToImage(r.Image) var out, errout bytes.Buffer runArgs := []string{ "run", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/commands/fn/render/cmdrender.go new/kpt-cli-1.0.0~beta.67/commands/fn/render/cmdrender.go --- old/kpt-cli-1.0.0~beta.66/commands/fn/render/cmdrender.go 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/commands/fn/render/cmdrender.go 2026-07-13 15:16:28.000000000 +0200 @@ -36,8 +36,8 @@ // NewRunner returns a command runner func NewRunner(ctx context.Context, parent string) *Runner { r := &Runner{ctx: ctx} - r.InitDefaults() + // Image prefix resolution priority: --image-prefix flag, then $KPT_IMAGE_PREFIX, then the built-in GHCR prefix. c := &cobra.Command{ Use: "render [PKG_PATH] [flags]", Short: docs.RenderShort, @@ -46,6 +46,9 @@ RunE: r.runE, PreRunE: r.preRunE, } + r.InitDefaults() + c.Flags().StringVar(&r.RunnerOptions.ImagePrefix, "image-prefix", runneroptions.DefaultImagePrefix(), + fmt.Sprintf("The prefix used when converting from short path to the full URL (defaults to $%s if set)", runneroptions.PrefixEnvVar)) c.Flags().StringVar(&r.resultsDirPath, "results-dir", "", "path to a directory to save function results") c.Flags().StringVarP(&r.dest, "output", "o", "", @@ -119,6 +122,9 @@ } func (r *Runner) runE(_ *cobra.Command, _ []string) error { + if err := r.RunnerOptions.ValidatePrefix(); err != nil { + return err + } var output io.Writer outContent := bytes.Buffer{} if r.dest != "" { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/documentation/content/en/book/04-using-functions/_index.md new/kpt-cli-1.0.0~beta.67/documentation/content/en/book/04-using-functions/_index.md --- old/kpt-cli-1.0.0~beta.66/documentation/content/en/book/04-using-functions/_index.md 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/documentation/content/en/book/04-using-functions/_index.md 2026-07-13 15:16:28.000000000 +0200 @@ -188,7 +188,14 @@ #### `image` -The `image` field specifies the container image for the function. You can specify an image from any container registry. If the registry is omitted, the default container registry for the functions catalog (`ghcr.io/kptdev/krm-functions-catalog`) is prepended automatically. For example, `set-labels:latest` is automatically expanded to `ghcr.io/kptdev/krm-functions-catalog/set-labels:latest`. +The `image` field specifies the container image for the function. You can specify an image from any container registry. If the registry is omitted, a default prefix is prepended automatically. By default, this prefix is `ghcr.io/kptdev/krm-functions-catalog`. For example, `set-labels:latest` is automatically expanded to `ghcr.io/kptdev/krm-functions-catalog/set-labels:latest`. + +The default prefix can be customized in two ways: + +1. Using the `--image-prefix` flag on commands like `kpt fn render` and `kpt fn eval` +2. Setting the `KPT_IMAGE_PREFIX` environment variable + +If both are specified, the command-line flag takes precedence over the environment variable. #### `tag` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/documentation/content/en/reference/cli/fn/eval/_index.md new/kpt-cli-1.0.0~beta.67/documentation/content/en/reference/cli/fn/eval/_index.md --- old/kpt-cli-1.0.0~beta.66/documentation/content/en/reference/cli/fn/eval/_index.md 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/documentation/content/en/reference/cli/fn/eval/_index.md 2026-07-13 15:16:28.000000000 +0200 @@ -76,10 +76,18 @@ --image, i: Container image of the function to execute e.g. `ghcr.io/kptdev/krm-functions-catalog/set-namespace:latest`. - For convenience, if full image path is not specified, `ghcr.io/kptdev/krm-functions-catalog/` is added as default prefix. + For convenience, if full image path is not specified, a default prefix is added. + The default prefix is `ghcr.io/kptdev/krm-functions-catalog/`, but can be customized via the + `--image-prefix` flag or `KPT_IMAGE_PREFIX` environment variable. e.g. instead of passing `ghcr.io/kptdev/krm-functions-catalog/set-namespace:latest` you can pass `set-namespace:latest`. `eval` executes only one function, so do not use `--exec` flag with this flag. +--image-prefix: + The container registry prefix to prepend to short image names when resolving functions. + This allows customization of the default registry instead of using the hardcoded default + (`ghcr.io/kptdev/krm-functions-catalog`). Can also be set via the KPT_IMAGE_PREFIX environment + variable. The command-line flag takes precedence over the environment variable. + --image-pull-policy: If the image should be pulled before rendering the package(s). It can be set to one of always, ifNotPresent, never. If unspecified, always will be the @@ -152,6 +160,10 @@ #### Environment Variables ```shell +KPT_IMAGE_PREFIX: + The default container registry prefix to use when resolving short image names. + This can be overridden by the --image-prefix flag. + KRM_FN_RUNTIME: The runtime to run kpt functions. It must be one of "docker", "podman" and "nerdctl". ``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/documentation/content/en/reference/cli/fn/render/_index.md new/kpt-cli-1.0.0~beta.67/documentation/content/en/reference/cli/fn/render/_index.md --- old/kpt-cli-1.0.0~beta.66/documentation/content/en/reference/cli/fn/render/_index.md 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/documentation/content/en/reference/cli/fn/render/_index.md 2026-07-13 15:16:28.000000000 +0200 @@ -53,6 +53,9 @@ --allow-network: Allow functions to access network during pipeline execution. Default: `false`. Note that this is applicable to container based functions only. +--image-prefix: + The container registry prefix to prepend to short image names when resolving functions. This allows customization of the default registry instead of using the hardcoded default (`ghcr.io/kptdev/krm-functions-catalog`). Can also be set via the KPT_IMAGE_PREFIX environment variable. The command-line flag takes precedence over the environment variable. + --image-pull-policy: If the image should be pulled before rendering the package(s). It can be set to one of always, ifNotPresent, never. If unspecified, always will be the @@ -89,6 +92,9 @@ #### Environment Variables ```shell +KPT_IMAGE_PREFIX: + The default container registry prefix to use when resolving short image names. This can be overridden by the --image-prefix flag. + KRM_FN_RUNTIME: The runtime to run kpt functions. It must be one of "docker", "podman" and "nerdctl". ``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/go.mod new/kpt-cli-1.0.0~beta.67/go.mod --- old/kpt-cli-1.0.0~beta.66/go.mod 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/go.mod 2026-07-13 15:16:28.000000000 +0200 @@ -14,7 +14,7 @@ github.com/google/go-containerregistry v0.21.6 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/kptdev/kpt/api v0.0.2 - github.com/kptdev/krm-functions-sdk/go/fn v1.1.0 + github.com/kptdev/krm-functions-sdk/go/fn v1.1.1 github.com/otiai10/copy v1.14.1 github.com/philopon/go-toposort v0.0.0-20170620085441-9be86dbd762f github.com/pkg/errors v0.9.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/go.sum new/kpt-cli-1.0.0~beta.67/go.sum --- old/kpt-cli-1.0.0~beta.66/go.sum 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/go.sum 2026-07-13 15:16:28.000000000 +0200 @@ -112,8 +112,8 @@ github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/kptdev/kpt/api v0.0.2 h1:0AWWhw8/LapkPwDwImtJXUDx81U9nW+joYIzCl3S/68= github.com/kptdev/kpt/api v0.0.2/go.mod h1:D/WM1LJ/HvHt3cHxDs2mF6mXkA37BbD1nrcsAVWgbfE= -github.com/kptdev/krm-functions-sdk/go/fn v1.1.0 h1:1+N9XdER7fGimWAUm35UWyRQfpx5b92nZlQGtuYdb5c= -github.com/kptdev/krm-functions-sdk/go/fn v1.1.0/go.mod h1:rPrLdh02mfqq5PjZRrMr5mhRA6dkjKm7O4bm5VZJWOg= +github.com/kptdev/krm-functions-sdk/go/fn v1.1.1 h1:F/tdu0FSWSnLaAV+AC8CVS0YGpUwkVnAs+O5NHPRmQU= +github.com/kptdev/krm-functions-sdk/go/fn v1.1.1/go.mod h1:rPrLdh02mfqq5PjZRrMr5mhRA6dkjKm7O4bm5VZJWOg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/healthcheck/go.mod new/kpt-cli-1.0.0~beta.67/healthcheck/go.mod --- old/kpt-cli-1.0.0~beta.66/healthcheck/go.mod 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/healthcheck/go.mod 2026-07-13 15:16:28.000000000 +0200 @@ -15,7 +15,7 @@ github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/x448/float16 v0.8.4 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect - golang.org/x/net v0.54.0 // indirect + golang.org/x/net v0.55.0 // indirect golang.org/x/text v0.37.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect k8s.io/klog/v2 v2.140.0 // indirect diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/healthcheck/go.sum new/kpt-cli-1.0.0~beta.67/healthcheck/go.sum --- old/kpt-cli-1.0.0~beta.66/healthcheck/go.sum 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/healthcheck/go.sum 2026-07-13 15:16:28.000000000 +0200 @@ -44,12 +44,12 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= +golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= +golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= -golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/pkg/lib/runneroptions/runneroptions.go new/kpt-cli-1.0.0~beta.67/pkg/lib/runneroptions/runneroptions.go --- old/kpt-cli-1.0.0~beta.66/pkg/lib/runneroptions/runneroptions.go 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/pkg/lib/runneroptions/runneroptions.go 2026-07-13 15:16:28.000000000 +0200 @@ -17,16 +17,24 @@ import ( "fmt" + "net/url" + "os" "strings" ) const ( FuncGenPkgContext = "builtins/gen-pkg-context" GHCRImagePrefix = "ghcr.io/kptdev/krm-functions-catalog/" + PrefixEnvVar = "KPT_IMAGE_PREFIX" ) -// ImageResolveFunc is the type for a function that can resolve a partial image to a (more) fully-qualified name -type ImageResolveFunc func(image string) string +// DefaultImagePrefix returns the image prefix from the KPT_IMAGE_PREFIX env var, or GHCRImagePrefix if unset. +func DefaultImagePrefix() string { + if p := os.Getenv(PrefixEnvVar); p != "" { + return p + } + return GHCRImagePrefix +} type RunnerOptions struct { // ImagePullPolicy controls the image pulling behavior before running the container. @@ -55,31 +63,50 @@ // enabled explicitly. AllowWasm bool - // ResolveToImage will resolve a partial image to a fully-qualified one - ResolveToImage ImageResolveFunc + // ImagePrefix determines the prefix ResolveToImage will use when resolving a + // partial image reference to a fully qualified image reference + ImagePrefix string } func (opts *RunnerOptions) InitDefaults(defaultImagePrefix string) { opts.ImagePullPolicy = IfNotPresentPull - opts.ResolveToImage = ResolveToImageForCLIFunc(defaultImagePrefix) + opts.ImagePrefix = defaultImagePrefix } -// ResolveToImageForCLIFunc returns a func that converts the KRM function short path to the full image url. +// ResolveToImage converts the KRM function short path to the full image url. // If the function is a catalog function, it prepends `prefix`, e.g. "set-namespace:v0.1" --> prefix + "set-namespace:v0.1". // A "/" is appended to `prefix` if it is not an empty string and does not end with a "/". -func ResolveToImageForCLIFunc(prefix string) ImageResolveFunc { - prefix = strings.TrimRight(prefix, "/") +func (opts RunnerOptions) ResolveToImage(image string) string { + prefix := strings.TrimRight(opts.ImagePrefix, "/") if prefix == "" { - return func(image string) string { - return image - } - } - return func(image string) string { - if !strings.Contains(image, "/") { - return fmt.Sprintf("%s/%s", prefix, image) - } return image } + if !strings.Contains(image, "/") { + return fmt.Sprintf("%s/%s", prefix, image) + } + return image +} + +// ValidatePrefix checks that ImagePrefix is a valid registry path. +func (opts RunnerOptions) ValidatePrefix() error { + if opts.ImagePrefix == "" { + return nil + } + prefix := strings.TrimRight(opts.ImagePrefix, "/") + // Reject prefixes that include a URL scheme + if strings.Contains(prefix, "://") { + return fmt.Errorf("invalid image prefix %q: must not include a scheme (e.g. https://)", opts.ImagePrefix) + } + // Reject fragments and query strings + if strings.ContainsAny(prefix, "?#") { + return fmt.Errorf("invalid image prefix %q: must not contain '?' or '#'", opts.ImagePrefix) + } + // Prepend a scheme so url.Parse can validate the host/path structure + u, err := url.Parse("https://" + prefix) + if err != nil || u.Host == "" { + return fmt.Errorf("invalid image prefix %q: must be a valid registry path", opts.ImagePrefix) + } + return nil } type SingleLineFormatter struct { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/pkg/lib/runneroptions/runneroptions_test.go new/kpt-cli-1.0.0~beta.67/pkg/lib/runneroptions/runneroptions_test.go --- old/kpt-cli-1.0.0~beta.66/pkg/lib/runneroptions/runneroptions_test.go 1970-01-01 01:00:00.000000000 +0100 +++ new/kpt-cli-1.0.0~beta.67/pkg/lib/runneroptions/runneroptions_test.go 2026-07-13 15:16:28.000000000 +0200 @@ -0,0 +1,121 @@ +// Copyright 2026 The kpt Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package runneroptions + +import ( + "os" + "testing" +) + +func TestValidatePrefix(t *testing.T) { + tests := []struct { + name string + prefix string + wantErr bool + }{ + // valid prefixes + {"empty prefix", "", false}, + {"default GHCR prefix", GHCRImagePrefix, false}, + {"custom registry with org", "my-registry.io/org/", false}, + {"registry with port", "localhost:5000/path/", false}, + {"registry with port no trailing slash", "localhost:5000/path", false}, + {"nested path", "registry.example.com/team/subdir/", false}, + {"simple hostname with path", "gcr.io/my-project/", false}, + {"hyphenated registry", "my-cool-registry.io/functions/", false}, + {"registry with subdomain", "docker.pkg.github.com/owner/repo/", false}, + {"ip address registry", "192.168.1.100:5000/images/", false}, + {"no trailing slash", "ghcr.io/org", false}, + + // invalid prefixes + {"has https scheme", "https://ghcr.io/org/", true}, + {"has http scheme", "http://registry.io/path/", true}, + {"whitespace in prefix", "my registry.io/org/", true}, + {"tab in prefix", "my\tregistry.io/org/", true}, + {"only a slash", "/", true}, + {"only path no host", "/just/a/path/", true}, + {"scheme with bad format", "://bad", true}, + {"fragment in prefix", "registry.io/path#fragment", true}, + {"query string in prefix", "registry.io/path?query=1", true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + opts := RunnerOptions{ImagePrefix: tt.prefix} + err := opts.ValidatePrefix() + if (err != nil) != tt.wantErr { + t.Errorf("ValidatePrefix(%q) error = %v, wantErr %v", tt.prefix, err, tt.wantErr) + } + }) + } +} + +func TestResolveToImage(t *testing.T) { + tests := []struct { + name string + prefix string + image string + expected string + }{ + // with default prefix + {"short image gets prefix", GHCRImagePrefix, "set-namespace:v0.1", "ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.1"}, + {"fully qualified image unchanged", GHCRImagePrefix, "gcr.io/my-project/my-fn:v1", "gcr.io/my-project/my-fn:v1"}, + {"image with org slash unchanged", GHCRImagePrefix, "myorg/my-fn:latest", "myorg/my-fn:latest"}, + + // with custom prefix + {"custom prefix applied", "my-registry.io/functions/", "apply-setters:v0.2", "my-registry.io/functions/apply-setters:v0.2"}, + {"custom prefix no trailing slash", "my-registry.io/functions", "apply-setters:v0.2", "my-registry.io/functions/apply-setters:v0.2"}, + {"custom prefix with fully qualified", "my-registry.io/functions/", "other.io/org/fn:v1", "other.io/org/fn:v1"}, + + // with empty prefix + {"empty prefix returns image as-is", "", "set-namespace:v0.1", "set-namespace:v0.1"}, + {"empty prefix fully qualified unchanged", "", "gcr.io/project/fn:v1", "gcr.io/project/fn:v1"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + opts := RunnerOptions{ImagePrefix: tt.prefix} + got := opts.ResolveToImage(tt.image) + if got != tt.expected { + t.Errorf("ResolveToImage(%q) with prefix %q = %q, want %q", tt.image, tt.prefix, got, tt.expected) + } + }) + } +} + +func TestDefaultImagePrefix(t *testing.T) { + t.Run("returns env var when set", func(t *testing.T) { + t.Setenv(PrefixEnvVar, "custom-registry.io/functions/") + got := DefaultImagePrefix() + if got != "custom-registry.io/functions/" { + t.Errorf("DefaultImagePrefix() = %q, want %q", got, "custom-registry.io/functions/") + } + }) + + t.Run("returns GHCR default when env var empty", func(t *testing.T) { + t.Setenv(PrefixEnvVar, "") + got := DefaultImagePrefix() + if got != GHCRImagePrefix { + t.Errorf("DefaultImagePrefix() = %q, want %q", got, GHCRImagePrefix) + } + }) + + t.Run("returns GHCR default when env var unset", func(t *testing.T) { + os.Unsetenv(PrefixEnvVar) + got := DefaultImagePrefix() + if got != GHCRImagePrefix { + t.Errorf("DefaultImagePrefix() = %q, want %q", got, GHCRImagePrefix) + } + }) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/release/images/Dockerfile new/kpt-cli-1.0.0~beta.67/release/images/Dockerfile --- old/kpt-cli-1.0.0~beta.66/release/images/Dockerfile 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/release/images/Dockerfile 2026-07-13 15:16:28.000000000 +0200 @@ -1,4 +1,4 @@ -# Copyright 2019 The kpt Authors +# Copyright 2019,2026 The kpt Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,11 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.18 +FROM alpine:3 +ARG TARGETPLATFORM RUN apk update && apk upgrade && \ apk add --no-cache git less mandoc diffutils bash openssh docker-cli && \ rm -rf /var/lib/apt/lists/* && \ rm /var/cache/apk/* -# This is set up for the Dockerfile to be used by goreleaser: https://goreleaser.com/customization/docker/ -COPY kpt /usr/local/bin/kpt +# This is set up for the Dockerfile to be used by goreleaser: https://goreleaser.com/customization/package/dockers_v2/ +COPY ${TARGETPLATFORM}/kpt /usr/local/bin/kpt ENTRYPOINT ["kpt"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/release/tag/goreleaser.yaml new/kpt-cli-1.0.0~beta.67/release/tag/goreleaser.yaml --- old/kpt-cli-1.0.0~beta.66/release/tag/goreleaser.yaml 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/release/tag/goreleaser.yaml 2026-07-13 15:16:28.000000000 +0200 @@ -1,4 +1,4 @@ -# Copyright 2019 The kpt Authors +# Copyright 2019,2026 The kpt Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -64,23 +64,29 @@ - arm64 ldflags: -s -w -X github.com/kptdev/kpt/run.version={{.Version}} -extldflags "-z noexecstack" -dockers: +dockers_v2: - ids: - linux-amd64 - image_templates: - - "ghcr.io/kptdev/kpt:{{ .Tag }}" - dockerfile: "release/images/Dockerfile" - build_flag_templates: - - "--label=org.opencontainers.image.title={{ .ProjectName }}" - - "--label=org.opencontainers.image.description=kpt - Automate Kubernetes Configuration Editing" - - "--label=org.opencontainers.image.url=https://github.com/{{ .Env.GITHUB_REPOSITORY | default \"kptdev/kpt\" }}" - - "--label=org.opencontainers.image.source=https://github.com/{{ .Env.GITHUB_REPOSITORY | default \"kptdev/kpt\" }}" - - "--label=org.opencontainers.image.version={{ .Tag }}" - - "--label=org.opencontainers.image.revision={{ .FullCommit }}" - - "--label=org.opencontainers.image.created={{ now | date \"2006-01-02T15:04:05Z07:00\" }}" + - linux-arm64 + images: + - ghcr.io/kptdev/kpt + tags: + - "{{ .Tag }}" + dockerfile: release/images/Dockerfile + platforms: + - linux/amd64 + - linux/arm64 + labels: + org.opencontainers.image.title: "{{ .ProjectName }}" + org.opencontainers.image.description: "kpt - Automate Kubernetes Configuration Editing" + org.opencontainers.image.url: "https://github.com/{{ envOrDefault \"GITHUB_REPOSITORY\" \"kptdev/kpt\" }}" + org.opencontainers.image.source: "https://github.com/{{ envOrDefault \"GITHUB_REPOSITORY\" \"kptdev/kpt\" }}" + org.opencontainers.image.version: "{{ .Tag }}" + org.opencontainers.image.revision: "{{ .FullCommit }}" + org.opencontainers.image.created: "{{ .Date }}" archives: - id: archived - builds: + ids: - darwin-amd64 - darwin-arm64 - linux-amd64 @@ -90,8 +96,8 @@ - lib.zip* name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}-{{ .Version }}" - id: bin-only - format: binary - builds: + formats: binary + ids: - darwin-amd64 - darwin-arm64 - linux-amd64 @@ -100,7 +106,7 @@ checksum: name_template: "checksums.txt" snapshot: - name_template: "master" + version_template: "master" changelog: sort: asc filters: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/thirdparty/cmdconfig/commands/cmdeval/cmdeval.go new/kpt-cli-1.0.0~beta.67/thirdparty/cmdconfig/commands/cmdeval/cmdeval.go --- old/kpt-cli-1.0.0~beta.66/thirdparty/cmdconfig/commands/cmdeval/cmdeval.go 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/thirdparty/cmdconfig/commands/cmdeval/cmdeval.go 2026-07-13 15:16:28.000000000 +0200 @@ -46,6 +46,9 @@ PreRunE: r.preRunE, } r.Command = c + + r.Command.Flags().StringVar(&r.RunnerOptions.ImagePrefix, "image-prefix", runneroptions.DefaultImagePrefix(), + fmt.Sprintf("The prefix used when converting from short path to the full URL (defaults to $%s if set)", runneroptions.PrefixEnvVar)) r.Command.Flags().StringVarP(&r.Dest, "output", "o", "", fmt.Sprintf("output resources are written to provided location. Allowed values: %s|%s|<OUT_DIR_PATH>", cmdutil.Stdout, cmdutil.Unwrap)) r.Command.Flags().StringVarP( @@ -450,6 +453,10 @@ func (r *EvalFnRunner) preRunE(c *cobra.Command, args []string) error { // separate the optional flag validation to fix linter issue: cyclomatic complexity + + if err := r.RunnerOptions.ValidatePrefix(); err != nil { + return err + } if err := r.validateOptionalFlags(); err != nil { return err } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kpt-cli-1.0.0~beta.66/thirdparty/cmdconfig/commands/cmdeval/cmdeval_test.go new/kpt-cli-1.0.0~beta.67/thirdparty/cmdconfig/commands/cmdeval/cmdeval_test.go --- old/kpt-cli-1.0.0~beta.66/thirdparty/cmdconfig/commands/cmdeval/cmdeval_test.go 2026-07-08 18:53:44.000000000 +0200 +++ new/kpt-cli-1.0.0~beta.67/thirdparty/cmdconfig/commands/cmdeval/cmdeval_test.go 2026-07-13 15:16:28.000000000 +0200 @@ -24,6 +24,7 @@ // TestRunFnCommand_preRunE verifies that preRunE correctly parses the commandline // flags and arguments into the RunFns structure to be executed. func TestRunFnCommand_preRunE(t *testing.T) { + t.Setenv(runneroptions.PrefixEnvVar, "") tempDir, err := os.MkdirTemp("", "") if !assert.NoError(t, err) { t.FailNow() @@ -220,6 +221,7 @@ ResultsDir: "foo/", RunnerOptions: runneroptions.RunnerOptions{ ImagePullPolicy: runneroptions.IfNotPresentPull, + ImagePrefix: runneroptions.GHCRImagePrefix, }, Env: []string{}, ContinueOnEmptyResult: true, @@ -261,6 +263,7 @@ Path: dir, RunnerOptions: runneroptions.RunnerOptions{ ImagePullPolicy: runneroptions.IfNotPresentPull, + ImagePrefix: runneroptions.GHCRImagePrefix, }, Env: []string{"FOO=BAR", "BAR"}, ContinueOnEmptyResult: true, @@ -288,6 +291,7 @@ AsCurrentUser: true, RunnerOptions: runneroptions.RunnerOptions{ ImagePullPolicy: runneroptions.IfNotPresentPull, + ImagePrefix: runneroptions.GHCRImagePrefix, }, Env: []string{}, ContinueOnEmptyResult: true, @@ -431,7 +435,6 @@ if tt.expectedStruct != nil { r.runFns.Function = nil r.runFns.FnConfig = nil - r.runFns.RunnerOptions.ResolveToImage = nil tt.expectedStruct.FnConfigPath = tt.fnConfigPath if !assert.Equal(t, *tt.expectedStruct, r.runFns) { t.FailNow() ++++++ kpt-cli.obsinfo ++++++ --- /var/tmp/diff_new_pack.8xi92S/_old 2026-07-14 13:51:26.742105034 +0200 +++ /var/tmp/diff_new_pack.8xi92S/_new 2026-07-14 13:51:26.754105445 +0200 @@ -1,5 +1,5 @@ name: kpt-cli -version: 1.0.0~beta.66 -mtime: 1783529624 -commit: 30c074ce1f9ab17958207ada884564ccc2cc5d13 +version: 1.0.0~beta.67 +mtime: 1783948588 +commit: 6bfa2af14026843300e6b3289cb6f78e2bc8be47 ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/kpt-cli/vendor.tar.gz /work/SRC/openSUSE:Factory/.kpt-cli.new.1991/vendor.tar.gz differ: char 30, line 1
