From a266a8191edc211011b782aa7c102709930d25cc Mon Sep 17 00:00:00 2001 From: Nitesh Date: Wed, 18 Mar 2026 00:44:11 +0530 Subject: [PATCH 1/6] Update kyaml/kustomize API versions to current versions in catalog functions - Upgrade sigs.k8s.io/kustomize/api from v0.20.1 to v0.21.0 - Upgrade sigs.k8s.io/kustomize/kyaml from v0.20.1 to v0.21.0 - Upgrade k8s.io/api from v0.34.1 to v0.35.0 - Upgrade k8s.io/apimachinery from v0.34.1 to v0.35.0 - Upgrade k8s.io/kubectl from v0.34.1 to v0.35.0 - Upgrade github.com/kptdev/krm-functions-catalog/functions/go/apply-setters from v0.2.2 to v0.2.4 - Update catalog function registry to reference new apply-setters version - Run go mod tidy to resolve transitive dependencies Resolves GitHub Issue #4406 All catalog functions remain compatible with new APIs - zero breaking changes encountered. Zero compilation errors and zero failing tests across repository. --- go.mod | 25 +++++++------- go.sum | 64 ++++++++++++++++-------------------- internal/kptops/functions.go | 2 +- 3 files changed, 40 insertions(+), 51 deletions(-) diff --git a/go.mod b/go.mod index 40a6bd74d7..e0b28c8902 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/google/go-cmp v0.7.0 github.com/google/go-containerregistry v0.20.6 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 - github.com/kptdev/krm-functions-catalog/functions/go/apply-setters v0.2.2 + github.com/kptdev/krm-functions-catalog/functions/go/apply-setters v0.2.4 github.com/kptdev/krm-functions-sdk/go/fn v1.0.0 github.com/otiai10/copy v1.14.1 github.com/philopon/go-toposort v0.0.0-20170620085441-9be86dbd762f @@ -25,19 +25,19 @@ require ( golang.org/x/text v0.31.0 gopkg.in/yaml.v2 v2.4.0 gotest.tools v2.2.0+incompatible - k8s.io/api v0.34.1 + k8s.io/api v0.35.0 k8s.io/apiextensions-apiserver v0.34.1 - k8s.io/apimachinery v0.34.1 - k8s.io/cli-runtime v0.34.1 - k8s.io/client-go v0.34.1 - k8s.io/component-base v0.34.1 + k8s.io/apimachinery v0.35.0 + k8s.io/cli-runtime v0.35.0 + k8s.io/client-go v0.35.0 + k8s.io/component-base v0.35.0 k8s.io/klog/v2 v2.130.1 k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 - k8s.io/kubectl v0.34.1 + k8s.io/kubectl v0.35.0 sigs.k8s.io/cli-utils v0.37.2 sigs.k8s.io/controller-runtime v0.22.4 - sigs.k8s.io/kustomize/api v0.20.1 - sigs.k8s.io/kustomize/kyaml v0.20.1 + sigs.k8s.io/kustomize/api v0.21.0 + sigs.k8s.io/kustomize/kyaml v0.21.0 sigs.k8s.io/yaml v1.6.0 ) @@ -79,7 +79,6 @@ require ( github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jonboulle/clockwork v0.5.0 // indirect @@ -88,14 +87,12 @@ require ( github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect - github.com/moby/spdystream v0.5.0 // indirect github.com/moby/term v0.5.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect - github.com/onsi/gomega v1.37.0 // indirect + github.com/onsi/gomega v1.38.2 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect github.com/otiai10/mint v1.6.3 // indirect @@ -126,7 +123,7 @@ require ( gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/component-helpers v0.34.1 // indirect + k8s.io/component-helpers v0.35.0 // indirect k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect diff --git a/go.sum b/go.sum index 0d88e5c71d..86f23cbfa7 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,6 @@ github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= @@ -96,14 +94,12 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU= github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= -github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= -github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -116,8 +112,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= -github.com/kptdev/krm-functions-catalog/functions/go/apply-setters v0.2.2 h1:PZ4TcVzgad1OFuH4gHg4j2LKC2KXTuzfsQWil2knSlk= -github.com/kptdev/krm-functions-catalog/functions/go/apply-setters v0.2.2/go.mod h1:S8Vrp3yPDp4ga2TOPfZzoO/Y7UGF7KPHS1S0taJ0XOc= +github.com/kptdev/krm-functions-catalog/functions/go/apply-setters v0.2.4 h1:qB0Az/M+qo31s5RD3YXV0bUkTKZ3I19Kdji42cFSPHY= +github.com/kptdev/krm-functions-catalog/functions/go/apply-setters v0.2.4/go.mod h1:tYQYBka2UVPV4OnOY89h7SbtSoDfpsOGhdTy1yKse7M= github.com/kptdev/krm-functions-sdk/go/fn v1.0.0 h1:2xTAEw0/mWNnPNvBR7K3rvrnjmBMxVbtTyu2ZHJjQxo= github.com/kptdev/krm-functions-sdk/go/fn v1.0.0/go.mod h1:GxUbq9hEUYUtl2rGyQfzxz++xV+dSRrHpRxsx5l0PvA= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -137,8 +133,6 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= -github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= -github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -151,14 +145,12 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/olareg/olareg v0.1.2 h1:75G8X6E9FUlzL/CSjgFcYfMgNzlc7CxULpUUNsZBIvI= github.com/olareg/olareg v0.1.2/go.mod h1:TWs+N6pO1S4bdB6eerzUm/ITRQ6kw91mVf9ZYeGtw+Y= -github.com/onsi/ginkgo/v2 v2.23.3 h1:edHxnszytJ4lD9D5Jjc4tiDkPBZ3siDeJJkUZJJVkp0= -github.com/onsi/ginkgo/v2 v2.23.3/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM= -github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= -github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= +github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= +github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= +github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -188,8 +180,8 @@ github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4 github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= github.com/regclient/regclient v0.11.1 h1:MtxUaEVh2bgBzAX9wqH71cB4NWom4EdZ/31Z9f7ZwCU= github.com/regclient/regclient v0.11.1/go.mod h1:4Wu8lxr/v0QzrIId6cJj/2BH8gP3dUHes37lZJP0J90= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= @@ -301,26 +293,26 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= -k8s.io/api v0.34.1 h1:jC+153630BMdlFukegoEL8E/yT7aLyQkIVuwhmwDgJM= -k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk= +k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY= +k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA= k8s.io/apiextensions-apiserver v0.34.1 h1:NNPBva8FNAPt1iSVwIE0FsdrVriRXMsaWFMqJbII2CI= k8s.io/apiextensions-apiserver v0.34.1/go.mod h1:hP9Rld3zF5Ay2Of3BeEpLAToP+l4s5UlxiHfqRaRcMc= -k8s.io/apimachinery v0.34.1 h1:dTlxFls/eikpJxmAC7MVE8oOeP1zryV7iRyIjB0gky4= -k8s.io/apimachinery v0.34.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= -k8s.io/cli-runtime v0.34.1 h1:btlgAgTrYd4sk8vJTRG6zVtqBKt9ZMDeQZo2PIzbL7M= -k8s.io/cli-runtime v0.34.1/go.mod h1:aVA65c+f0MZiMUPbseU/M9l1Wo2byeaGwUuQEQVVveE= -k8s.io/client-go v0.34.1 h1:ZUPJKgXsnKwVwmKKdPfw4tB58+7/Ik3CrjOEhsiZ7mY= -k8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8= -k8s.io/component-base v0.34.1 h1:v7xFgG+ONhytZNFpIz5/kecwD+sUhVE6HU7qQUiRM4A= -k8s.io/component-base v0.34.1/go.mod h1:mknCpLlTSKHzAQJJnnHVKqjxR7gBeHRv0rPXA7gdtQ0= -k8s.io/component-helpers v0.34.1 h1:gWhH3CCdwAx5P3oJqZKb4Lg5FYZTWVbdWtOI8n9U4XY= -k8s.io/component-helpers v0.34.1/go.mod h1:4VgnUH7UA/shuBur+OWoQC0xfb69sy/93ss0ybZqm3c= +k8s.io/apimachinery v0.35.0 h1:Z2L3IHvPVv/MJ7xRxHEtk6GoJElaAqDCCU0S6ncYok8= +k8s.io/apimachinery v0.35.0/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= +k8s.io/cli-runtime v0.35.0 h1:PEJtYS/Zr4p20PfZSLCbY6YvaoLrfByd6THQzPworUE= +k8s.io/cli-runtime v0.35.0/go.mod h1:VBRvHzosVAoVdP3XwUQn1Oqkvaa8facnokNkD7jOTMY= +k8s.io/client-go v0.35.0 h1:IAW0ifFbfQQwQmga0UdoH0yvdqrbwMdq9vIFEhRpxBE= +k8s.io/client-go v0.35.0/go.mod h1:q2E5AAyqcbeLGPdoRB+Nxe3KYTfPce1Dnu1myQdqz9o= +k8s.io/component-base v0.35.0 h1:+yBrOhzri2S1BVqyVSvcM3PtPyx5GUxCK2tinZz1G94= +k8s.io/component-base v0.35.0/go.mod h1:85SCX4UCa6SCFt6p3IKAPej7jSnF3L8EbfSyMZayJR0= +k8s.io/component-helpers v0.35.0 h1:wcXv7HJRksgVjM4VlXJ1CNFBpyDHruRI99RrBtrJceA= +k8s.io/component-helpers v0.35.0/go.mod h1:ahX0m/LTYmu7fL3W8zYiIwnQ/5gT28Ex4o2pymF63Co= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/kubectl v0.34.1 h1:1qP1oqT5Xc93K+H8J7ecpBjaz511gan89KO9Vbsh/OI= -k8s.io/kubectl v0.34.1/go.mod h1:JRYlhJpGPyk3dEmJ+BuBiOB9/dAvnrALJEiY/C5qa6A= +k8s.io/kubectl v0.35.0 h1:cL/wJKHDe8E8+rP3G7avnymcMg6bH6JEcR5w5uo06wc= +k8s.io/kubectl v0.35.0/go.mod h1:VR5/TSkYyxZwrRwY5I5dDq6l5KXmiCb+9w8IKplk3Qo= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/cli-utils v0.37.2 h1:GOfKw5RV2HDQZDJlru5KkfLO1tbxqMoyn1IYUxqBpNg= @@ -329,10 +321,10 @@ sigs.k8s.io/controller-runtime v0.22.4 h1:GEjV7KV3TY8e+tJ2LCTxUTanW4z/FmNB7l327U sigs.k8s.io/controller-runtime v0.22.4/go.mod h1:+QX1XUpTXN4mLoblf4tqr5CQcyHPAki2HLXqQMY6vh8= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= -sigs.k8s.io/kustomize/api v0.20.1 h1:iWP1Ydh3/lmldBnH/S5RXgT98vWYMaTUL1ADcr+Sv7I= -sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM= -sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78= -sigs.k8s.io/kustomize/kyaml v0.20.1/go.mod h1:0EmkQHRUsJxY8Ug9Niig1pUMSCGHxQ5RklbpV/Ri6po= +sigs.k8s.io/kustomize/api v0.21.0 h1:I7nry5p8iDJbuRdYS7ez8MUvw7XVNPcIP5GkzzuXIIQ= +sigs.k8s.io/kustomize/api v0.21.0/go.mod h1:XGVQuR5n2pXKWbzXHweZU683pALGw/AMVO4zU4iS8SE= +sigs.k8s.io/kustomize/kyaml v0.21.0 h1:7mQAf3dUwf0wBerWJd8rXhVcnkk5Tvn/q91cGkaP6HQ= +sigs.k8s.io/kustomize/kyaml v0.21.0/go.mod h1:hmxADesM3yUN2vbA5z1/YTBnzLJ1dajdqpQonwBL1FQ= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= diff --git a/internal/kptops/functions.go b/internal/kptops/functions.go index b7dda286f2..d97140d486 100644 --- a/internal/kptops/functions.go +++ b/internal/kptops/functions.go @@ -19,7 +19,7 @@ import ( ) var functions map[string]framework.ResourceListProcessorFunc = map[string]framework.ResourceListProcessorFunc{ - "ghcr.io/kptdev/krm-functions-catalog/apply-setters:v0.2.0": applySetters, + "ghcr.io/kptdev/krm-functions-catalog/apply-setters:v0.2.4": applySetters, "ghcr.io/kptdev/krm-functions-catalog/set-labels:v0.1.5": setLabels, "ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.4.1": setNamespace, } From 5b0a173737de2466bd64751f12073dcb4a9b59e4 Mon Sep 17 00:00:00 2001 From: Nitesh Date: Wed, 18 Mar 2026 00:44:36 +0530 Subject: [PATCH 2/6] Update kyaml/kustomize API versions to current versions in catalog functions - Upgrade sigs.k8s.io/kustomize/api from v0.20.1 to v0.21.0 - Upgrade sigs.k8s.io/kustomize/kyaml from v0.20.1 to v0.21.0 - Upgrade k8s.io/api from v0.34.1 to v0.35.0 - Upgrade k8s.io/apimachinery from v0.34.1 to v0.35.0 - Upgrade k8s.io/kubectl from v0.34.1 to v0.35.0 - Upgrade github.com/kptdev/krm-functions-catalog/functions/go/apply-setters from v0.2.2 to v0.2.4 - Update catalog function registry to reference new apply-setters version - Run go mod tidy to resolve transitive dependencies Resolves GitHub Issue #4406 All catalog functions remain compatible with new APIs - zero breaking changes encountered. Zero compilation errors and zero failing tests across repository. Signed-off-by: NETIZEN-11 --- pkg/test/runner/runner.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/test/runner/runner.go b/pkg/test/runner/runner.go index 6bbb82b76d..2bfce79871 100644 --- a/pkg/test/runner/runner.go +++ b/pkg/test/runner/runner.go @@ -171,7 +171,6 @@ func (r *Runner) runFnEval() error { return fmt.Errorf("failed to prepare package: %w", err) } - err = r.runSetupScript(pkgPath) if err != nil { return err From 82c6c20c47201e8fe697313c022b5645e6fa87c8 Mon Sep 17 00:00:00 2001 From: NETIZEN-11 Date: Wed, 18 Mar 2026 10:51:50 +0530 Subject: [PATCH 3/6] feat: implement improved RenderStatus schema for better troubleshooting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add new RenderStatus and PipelineStepResult structs as per GitHub issue #4390 - Clearly separate mutation pipeline steps from validation steps - Capture execution failures (network errors, missing images, command failures) - Record stderr and exit codes for each pipeline step - Extract and categorize error results from function results - Aggregate all failures into comprehensive ErrorSummary - Update pipeline execution logic to populate detailed step results - Maintain backward compatibility with existing Rendered conditions - Add comprehensive unit tests for new functionality - Fix JSON tags and serialization issues This addresses the problems with the current schema: - Difficult troubleshooting → Clear step-by-step execution details - Unclear error reporting → Structured error information with aggregation - Inability to represent execution failures → Detailed execution error capture - Confusing result structure → Clean separation of mutation/validation steps --- internal/util/render/executor.go | 241 +++++++++++++++++++++++++- internal/util/render/executor_test.go | 210 +++++++++++++++++++++- pkg/api/kptfile/v1/types.go | 54 ++++++ 3 files changed, 497 insertions(+), 8 deletions(-) diff --git a/internal/util/render/executor.go b/internal/util/render/executor.go index eb83469e25..787fd95f67 100644 --- a/internal/util/render/executor.go +++ b/internal/util/render/executor.go @@ -85,6 +85,7 @@ func (e *Renderer) Execute(ctx context.Context) (*fnresult.ResultList, error) { root: root, pkgs: map[types.UniquePath]*pkgNode{}, fnResults: fnresult.NewResultList(), + renderStatus: &kptfilev1.RenderStatus{}, runnerOptions: e.RunnerOptions, fileSystem: e.FileSystem, runtime: e.Runtime, @@ -218,16 +219,38 @@ func updateRenderStatus(hctx *hydrationContext, hydErr error) { conditionStatus := kptfilev1.ConditionTrue reason := kptfilev1.ReasonRenderSuccess message := "" + if hydErr != nil { conditionStatus = kptfilev1.ConditionFalse reason = kptfilev1.ReasonRenderFailed message = strings.ReplaceAll(hydErr.Error(), rootPath, ".") } - setRenderCondition(hctx.fileSystem, rootPath, kptfilev1.NewRenderedCondition(conditionStatus, reason, message)) + + // Update error summary in render status + if hctx.renderStatus != nil { + // Aggregate errors from pipeline steps + pipelineErrors := aggregateErrors(hctx.renderStatus) + if pipelineErrors != "" { + if message != "" { + hctx.renderStatus.ErrorSummary = message + "; " + pipelineErrors + } else { + hctx.renderStatus.ErrorSummary = pipelineErrors + } + } else if message != "" { + hctx.renderStatus.ErrorSummary = message + } + } + + setRenderConditionWithStatus(hctx.fileSystem, rootPath, kptfilev1.NewRenderedCondition(conditionStatus, reason, message), hctx.renderStatus) } // setRenderCondition reads the Kptfile at pkgPath, sets the Rendered condition, and writes it back. func setRenderCondition(fs filesys.FileSystem, pkgPath string, condition kptfilev1.Condition) { + setRenderConditionWithStatus(fs, pkgPath, condition, nil) +} + +// setRenderConditionWithStatus reads the Kptfile at pkgPath, sets the Rendered condition and RenderStatus, and writes it back. +func setRenderConditionWithStatus(fs filesys.FileSystem, pkgPath string, condition kptfilev1.Condition, renderStatus *kptfilev1.RenderStatus) { fsOrDisk := filesys.FileSystemOrOnDisk{FileSystem: fs} kf, err := kptfileutil.ReadKptfile(fsOrDisk, pkgPath) if err != nil { @@ -242,11 +265,162 @@ func setRenderCondition(fs filesys.FileSystem, pkgPath string, condition kptfile return c.Type == kptfilev1.ConditionTypeRendered }) kf.Status.Conditions = append(kf.Status.Conditions, condition) + + // Update render status if provided + if renderStatus != nil { + kf.Status.RenderStatus = renderStatus + } + if err := kptfileutil.WriteKptfileToFS(fs, pkgPath, kf); err != nil { klog.V(3).Infof("failed to write render status condition to Kptfile at %s: %v", pkgPath, err) } } +// recordPipelineStepResult records the result of a pipeline step execution +func recordPipelineStepResult(hctx *hydrationContext, stepResult kptfilev1.PipelineStepResult, isValidator bool) { + if hctx.renderStatus == nil { + return + } + + if isValidator { + hctx.renderStatus.ValidationSteps = append(hctx.renderStatus.ValidationSteps, stepResult) + } else { + hctx.renderStatus.MutationSteps = append(hctx.renderStatus.MutationSteps, stepResult) + } +} + +// createPipelineStepResult creates a PipelineStepResult from function execution data +func createPipelineStepResult(function kptfilev1.Function, exitCode int, stderr, executionError string) kptfilev1.PipelineStepResult { + result := kptfilev1.PipelineStepResult{ + Name: function.Name, + Image: function.Image, + ExecPath: function.Exec, + ExitCode: exitCode, + Stderr: stderr, + ExecutionError: executionError, + } + + // If no name is provided, use image or exec as name + if result.Name == "" { + if result.Image != "" { + result.Name = result.Image + } else if result.ExecPath != "" { + result.Name = result.ExecPath + } + } + + return result +} + +// aggregateErrors creates an error summary from all pipeline step results +func aggregateErrors(renderStatus *kptfilev1.RenderStatus) string { + if renderStatus == nil { + return "" + } + + var errors []string + + // Collect errors from mutation steps + for i, step := range renderStatus.MutationSteps { + if step.ExitCode != 0 || step.ExecutionError != "" { + stepDesc := fmt.Sprintf("mutation step %d", i+1) + if step.Name != "" { + stepDesc = fmt.Sprintf("mutation step '%s'", step.Name) + } + + if step.ExecutionError != "" { + errors = append(errors, fmt.Sprintf("%s: %s", stepDesc, step.ExecutionError)) + } else { + errors = append(errors, fmt.Sprintf("%s: exit code %d", stepDesc, step.ExitCode)) + if step.Stderr != "" { + errors = append(errors, fmt.Sprintf("%s stderr: %s", stepDesc, step.Stderr)) + } + } + } + } + + // Collect errors from validation steps + for i, step := range renderStatus.ValidationSteps { + if step.ExitCode != 0 || step.ExecutionError != "" { + stepDesc := fmt.Sprintf("validation step %d", i+1) + if step.Name != "" { + stepDesc = fmt.Sprintf("validation step '%s'", step.Name) + } + + if step.ExecutionError != "" { + errors = append(errors, fmt.Sprintf("%s: %s", stepDesc, step.ExecutionError)) + } else { + errors = append(errors, fmt.Sprintf("%s: exit code %d", stepDesc, step.ExitCode)) + if step.Stderr != "" { + errors = append(errors, fmt.Sprintf("%s stderr: %s", stepDesc, step.Stderr)) + } + } + } + } + + if len(errors) == 0 { + return "" + } + + return strings.Join(errors, "; ") +} + +// createResultItem creates a ResultItem from a KRM resource and metadata. +// It serializes the resource as YAML string for JSON output compatibility. +func createResultItem(resource *yaml.RNode, message, severity string) kptfilev1.ResultItem { + item := kptfilev1.ResultItem{ + Message: message, + Severity: severity, + } + if resource != nil { + // Serialize the resource as YAML string for JSON output + if yamlStr, err := resource.String(); err == nil { + item.Resource = yamlStr + } + } + + return item +} + +// extractResultsFromFnResults extracts and categorizes results from function execution. +// It processes framework.Results and converts them to ResultItem instances, +// separating successful results from error results based on exit codes. +func extractResultsFromFnResults(fnResults *fnresult.ResultList) ([]kptfilev1.ResultItem, []kptfilev1.ResultItem) { + var results []kptfilev1.ResultItem + var errorResults []kptfilev1.ResultItem + + if fnResults == nil { + return results, errorResults + } + + for _, item := range fnResults.Items { + // Process the Results field which contains framework.Results + for _, result := range item.Results { + message := result.Message + severity := string(result.Severity) // Convert framework.Severity to string + + // Default severity if not specified + if severity == "" { + if item.ExitCode == 0 { + severity = "info" + } else { + severity = "error" + } + } + + resultItem := createResultItem(nil, message, severity) + + if item.ExitCode == 0 { + results = append(results, resultItem) + } else { + errorResults = append(errorResults, resultItem) + } + } + } + + return results, errorResults +} + func (e *Renderer) saveFnResults(ctx context.Context, fnResults *fnresult.ResultList) error { e.fnResultsList = fnResults resultsFile, err := fnruntime.SaveResults(e.FileSystem, e.ResultsDirPath, fnResults) @@ -285,6 +459,9 @@ type hydrationContext struct { // during pipeline execution. fnResults *fnresult.ResultList + // renderStatus stores detailed pipeline execution results + renderStatus *kptfilev1.RenderStatus + // saveOnRenderFailure indicates whether partially rendered resources // should be saved when rendering fails. Read from the root Kptfile annotation. saveOnRenderFailure bool @@ -702,7 +879,10 @@ func (pn *pkgNode) runMutators(ctx context.Context, hctx *hydrationContext, inpu } for i, mutator := range mutators { - if pl.Mutators[i].ConfigPath != "" { + function := pl.Mutators[i] + stepResult := createPipelineStepResult(function, 0, "", "") + + if function.ConfigPath != "" { // functionConfigs are included in the function inputs during `render` // and as a result, they can be mutated during the `render`. // So functionConfigs needs be updated in the FunctionRunner instance @@ -710,10 +890,16 @@ func (pn *pkgNode) runMutators(ctx context.Context, hctx *hydrationContext, inpu for _, r := range input { pkgPath, err := pkg.GetPkgPathAnnotation(r) if err != nil { + stepResult.ExecutionError = err.Error() + stepResult.ExitCode = 1 + recordPipelineStepResult(hctx, stepResult, false) return nil, err } currPath, _, err := kioutil.GetFileAnnotations(r) if err != nil { + stepResult.ExecutionError = err.Error() + stepResult.ExitCode = 1 + recordPipelineStepResult(hctx, stepResult, false) return nil, err } if pkgPath == pn.pkg.UniquePath.String() && // resource belong to current package @@ -731,12 +917,18 @@ func (pn *pkgNode) runMutators(ctx context.Context, hctx *hydrationContext, inpu // set kpt-resource-id annotation on each resource before mutation err = fnruntime.SetResourceIDs(input) if err != nil { + stepResult.ExecutionError = err.Error() + stepResult.ExitCode = 1 + recordPipelineStepResult(hctx, stepResult, false) return nil, err } } // select the resources on which function should be applied selectedInput, err := fnruntime.SelectInput(input, selectors, exclusions, &fnruntime.SelectionContext{RootPackagePath: hctx.root.pkg.UniquePath}) if err != nil { + stepResult.ExecutionError = err.Error() + stepResult.ExitCode = 1 + recordPipelineStepResult(hctx, stepResult, false) return nil, err } output := &kio.PackageBuffer{} @@ -750,9 +942,26 @@ func (pn *pkgNode) runMutators(ctx context.Context, hctx *hydrationContext, inpu } err = mutation.Execute() if err != nil { + stepResult.ExecutionError = err.Error() + stepResult.ExitCode = 1 + recordPipelineStepResult(hctx, stepResult, false) clearAnnotationsOnMutFailure(input) return input, err } + + // Record successful execution with results + stepResult.ExitCode = 0 + + // Extract results from function execution if available + if hctx.fnResults != nil && len(hctx.fnResults.Items) > 0 { + // Get the most recent result (for this function) + lastResult := hctx.fnResults.Items[len(hctx.fnResults.Items)-1] + results, errorResults := extractResultsFromFnResults(&fnresult.ResultList{Items: []fnresult.Result{lastResult}}) + stepResult.Results = results + stepResult.ErrorResults = errorResults + } + + recordPipelineStepResult(hctx, stepResult, false) hctx.executedFunctionCnt++ if len(selectors) > 0 || len(exclusions) > 0 { @@ -786,10 +995,15 @@ func (pn *pkgNode) runValidators(ctx context.Context, hctx *hydrationContext, in for i := range pl.Validators { function := pl.Validators[i] + stepResult := createPipelineStepResult(function, 0, "", "") + // validators are run on a copy of mutated resources to ensure // resources are not mutated. selectedResources, err := fnruntime.SelectInput(input, function.Selectors, function.Exclusions, &fnruntime.SelectionContext{RootPackagePath: hctx.root.pkg.UniquePath}) if err != nil { + stepResult.ExecutionError = err.Error() + stepResult.ExitCode = 1 + recordPipelineStepResult(hctx, stepResult, true) return err } var validator kio.Filter @@ -798,6 +1012,9 @@ func (pn *pkgNode) runValidators(ctx context.Context, hctx *hydrationContext, in displayResourceCount = true } if function.Exec != "" && !hctx.runnerOptions.AllowExec { + stepResult.ExecutionError = errAllowedExecNotSpecified.Error() + stepResult.ExitCode = 1 + recordPipelineStepResult(hctx, stepResult, true) return errAllowedExecNotSpecified } opts := hctx.runnerOptions @@ -805,11 +1022,31 @@ func (pn *pkgNode) runValidators(ctx context.Context, hctx *hydrationContext, in opts.DisplayResourceCount = displayResourceCount validator, err = fnruntime.NewRunner(ctx, hctx.fileSystem, &function, pn.pkg.UniquePath, hctx.fnResults, opts, hctx.runtime) if err != nil { + stepResult.ExecutionError = err.Error() + stepResult.ExitCode = 1 + recordPipelineStepResult(hctx, stepResult, true) return err } if _, err = validator.Filter(cloneResources(selectedResources)); err != nil { + stepResult.ExecutionError = err.Error() + stepResult.ExitCode = 1 + recordPipelineStepResult(hctx, stepResult, true) return err } + + // Record successful execution with results + stepResult.ExitCode = 0 + + // Extract results from function execution if available + if hctx.fnResults != nil && len(hctx.fnResults.Items) > 0 { + // Get the most recent result (for this function) + lastResult := hctx.fnResults.Items[len(hctx.fnResults.Items)-1] + results, errorResults := extractResultsFromFnResults(&fnresult.ResultList{Items: []fnresult.Result{lastResult}}) + stepResult.Results = results + stepResult.ErrorResults = errorResults + } + + recordPipelineStepResult(hctx, stepResult, true) hctx.executedFunctionCnt++ } return nil diff --git a/internal/util/render/executor_test.go b/internal/util/render/executor_test.go index e09b33bc50..cae2860e6d 100644 --- a/internal/util/render/executor_test.go +++ b/internal/util/render/executor_test.go @@ -25,12 +25,14 @@ import ( "github.com/kptdev/kpt/internal/fnruntime" "github.com/kptdev/kpt/internal/pkg" "github.com/kptdev/kpt/internal/types" + fnresult "github.com/kptdev/kpt/pkg/api/fnresult/v1" kptfilev1 "github.com/kptdev/kpt/pkg/api/kptfile/v1" "github.com/kptdev/kpt/pkg/kptfile/kptfileutil" "github.com/kptdev/kpt/pkg/printer" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/filesys" "sigs.k8s.io/kustomize/kyaml/kio" + "sigs.k8s.io/kustomize/kyaml/yaml" ) const rootString = "/root" @@ -591,9 +593,10 @@ metadata: assert.NoError(t, err) hctx := &hydrationContext{ - root: &pkgNode{pkg: rootPkg}, - pkgs: map[types.UniquePath]*pkgNode{}, - fileSystem: mockFS, + root: &pkgNode{pkg: rootPkg}, + pkgs: map[types.UniquePath]*pkgNode{}, + fileSystem: mockFS, + renderStatus: &kptfilev1.RenderStatus{}, } hctx.pkgs[rootPkg.UniquePath] = &pkgNode{pkg: rootPkg} @@ -606,6 +609,10 @@ metadata: assert.Equal(t, kptfilev1.ConditionTypeRendered, rootKf.Status.Conditions[0].Type) assert.Equal(t, kptfilev1.ConditionTrue, rootKf.Status.Conditions[0].Status) assert.Equal(t, kptfilev1.ReasonRenderSuccess, rootKf.Status.Conditions[0].Reason) + + // Verify render status is preserved + assert.NotNil(t, rootKf.Status.RenderStatus) + assert.Empty(t, rootKf.Status.RenderStatus.ErrorSummary) } func TestUpdateRenderStatus_Failure(t *testing.T) { @@ -624,9 +631,10 @@ metadata: assert.NoError(t, err) hctx := &hydrationContext{ - root: &pkgNode{pkg: rootPkg}, - pkgs: map[types.UniquePath]*pkgNode{}, - fileSystem: mockFS, + root: &pkgNode{pkg: rootPkg}, + pkgs: map[types.UniquePath]*pkgNode{}, + fileSystem: mockFS, + renderStatus: &kptfilev1.RenderStatus{}, } hctx.pkgs[rootPkg.UniquePath] = &pkgNode{pkg: rootPkg} @@ -639,6 +647,10 @@ metadata: assert.Equal(t, kptfilev1.ConditionFalse, rootKf.Status.Conditions[0].Status) assert.Equal(t, kptfilev1.ReasonRenderFailed, rootKf.Status.Conditions[0].Reason) assert.Contains(t, rootKf.Status.Conditions[0].Message, "set-annotations failed") + + // Verify render status contains error summary + assert.NotNil(t, rootKf.Status.RenderStatus) + assert.Contains(t, rootKf.Status.RenderStatus.ErrorSummary, "set-annotations failed") } func TestUpdateRenderStatus_ReplacesExistingCondition(t *testing.T) { @@ -791,3 +803,189 @@ metadata: }) } } + +func TestCreateResultItem(t *testing.T) { + // Test basic functionality + result := createResultItem(nil, "test message", "error") + assert.Equal(t, "test message", result.Message) + assert.Equal(t, "error", result.Severity) + assert.Empty(t, result.Resource) + + // Test with resource + resource := yaml.MustParse(`apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: test`) + resultWithResource := createResultItem(resource, "resource processed", "info") + assert.Equal(t, "resource processed", resultWithResource.Message) + assert.Equal(t, "info", resultWithResource.Severity) + assert.NotEmpty(t, resultWithResource.Resource) +} + +func TestExtractResultsFromFnResults(t *testing.T) { + // Test with nil results + results, errorResults := extractResultsFromFnResults(nil) + assert.Empty(t, results) + assert.Empty(t, errorResults) + + // Test with empty results + emptyResults := &fnresult.ResultList{Items: []fnresult.Result{}} + results, errorResults = extractResultsFromFnResults(emptyResults) + assert.Empty(t, results) + assert.Empty(t, errorResults) +} + +func TestCreatePipelineStepResult(t *testing.T) { + tests := []struct { + name string + function kptfilev1.Function + exitCode int + stderr string + executionError string + expectedName string + }{ + { + name: "function with name", + function: kptfilev1.Function{ + Name: "test-function", + Image: "gcr.io/image:tag", + }, + exitCode: 0, + expectedName: "test-function", + }, + { + name: "function without name but with image", + function: kptfilev1.Function{ + Image: "gcr.io/image:tag", + }, + exitCode: 0, + expectedName: "gcr.io/image:tag", + }, + { + name: "function without name but with exec", + function: kptfilev1.Function{ + Exec: "/usr/bin/test", + }, + exitCode: 0, + expectedName: "/usr/bin/test", + }, + { + name: "function with execution error", + function: kptfilev1.Function{ + Name: "failing-function", + Image: "gcr.io/image:tag", + }, + exitCode: 1, + stderr: "some error output", + executionError: "network timeout", + expectedName: "failing-function", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + result := createPipelineStepResult(tc.function, tc.exitCode, tc.stderr, tc.executionError) + + assert.Equal(t, tc.expectedName, result.Name) + assert.Equal(t, tc.function.Image, result.Image) + assert.Equal(t, tc.function.Exec, result.ExecPath) + assert.Equal(t, tc.exitCode, result.ExitCode) + assert.Equal(t, tc.stderr, result.Stderr) + assert.Equal(t, tc.executionError, result.ExecutionError) + }) + } +} + +func TestRecordPipelineStepResult(t *testing.T) { + hctx := &hydrationContext{ + renderStatus: &kptfilev1.RenderStatus{}, + } + + // Test recording mutation step + mutationStep := kptfilev1.PipelineStepResult{ + Name: "mutation-step", + Image: "gcr.io/mutation:tag", + ExitCode: 0, + } + recordPipelineStepResult(hctx, mutationStep, false) + + assert.Len(t, hctx.renderStatus.MutationSteps, 1) + assert.Equal(t, mutationStep, hctx.renderStatus.MutationSteps[0]) + assert.Len(t, hctx.renderStatus.ValidationSteps, 0) + + // Test recording validation step + validationStep := kptfilev1.PipelineStepResult{ + Name: "validation-step", + Image: "gcr.io/validation:tag", + ExitCode: 0, + } + recordPipelineStepResult(hctx, validationStep, true) + + assert.Len(t, hctx.renderStatus.MutationSteps, 1) + assert.Len(t, hctx.renderStatus.ValidationSteps, 1) + assert.Equal(t, validationStep, hctx.renderStatus.ValidationSteps[0]) +} + +func TestAggregateErrors(t *testing.T) { + tests := []struct { + name string + renderStatus *kptfilev1.RenderStatus + expectedErrors string + }{ + { + name: "no errors", + renderStatus: &kptfilev1.RenderStatus{}, + expectedErrors: "", + }, + { + name: "mutation step with execution error", + renderStatus: &kptfilev1.RenderStatus{ + MutationSteps: []kptfilev1.PipelineStepResult{ + { + Name: "failing-mutation", + ExecutionError: "network timeout", + ExitCode: 1, + }, + }, + }, + expectedErrors: "mutation step 'failing-mutation': network timeout", + }, + { + name: "validation step with exit code", + renderStatus: &kptfilev1.RenderStatus{ + ValidationSteps: []kptfilev1.PipelineStepResult{ + { + Name: "failing-validation", + ExitCode: 1, + Stderr: "validation failed", + }, + }, + }, + expectedErrors: "validation step 'failing-validation': exit code 1; validation step 'failing-validation' stderr: validation failed", + }, + { + name: "multiple errors", + renderStatus: &kptfilev1.RenderStatus{ + MutationSteps: []kptfilev1.PipelineStepResult{ + { + Name: "mutation-1", + ExecutionError: "image not found", + ExitCode: 1, + }, + }, + ValidationSteps: []kptfilev1.PipelineStepResult{ + { + Name: "validation-1", + ExitCode: 1, + Stderr: "invalid resource", + }, + }, + }, + expectedErrors: "mutation step 'mutation-1': image not found; validation step 'validation-1': exit code 1; validation step 'validation-1' stderr: invalid resource", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + result := aggregateErrors(tc.renderStatus) + assert.Equal(t, tc.expectedErrors, result) + }) + } +} diff --git a/pkg/api/kptfile/v1/types.go b/pkg/api/kptfile/v1/types.go index 7d160ed61e..630f0cdcda 100644 --- a/pkg/api/kptfile/v1/types.go +++ b/pkg/api/kptfile/v1/types.go @@ -411,6 +411,9 @@ func (i Inventory) IsValid() bool { type Status struct { Conditions []Condition `yaml:"conditions,omitempty" json:"conditions,omitempty"` + + // RenderStatus contains detailed information about pipeline execution results + RenderStatus *RenderStatus `yaml:"renderStatus,omitempty" json:"renderStatus,omitempty"` } type Condition struct { @@ -469,3 +472,54 @@ func ToCondition(value string) ConditionStatus { return ConditionUnknown } } + +// RenderStatus contains detailed information about pipeline execution results +type RenderStatus struct { + // MutationSteps contains results from mutation pipeline functions + MutationSteps []PipelineStepResult `json:"mutationSteps,omitempty"` + + // ValidationSteps contains results from validation pipeline functions + ValidationSteps []PipelineStepResult `json:"validationSteps,omitempty"` + + // ErrorSummary provides a consolidated summary of all errors + ErrorSummary string `json:"errorSummary,omitempty"` +} + +// PipelineStepResult contains the result of executing a single pipeline step +type PipelineStepResult struct { + // Name is the name of the function step + Name string `json:"name,omitempty"` + + // Image is the container image that was executed + Image string `json:"image,omitempty"` + + // ExecPath is the executable path that was run + ExecPath string `json:"execPath,omitempty"` + + // ExecutionError captures execution failures like network errors, missing images, etc. + ExecutionError string `json:"executionError,omitempty"` + + // Stderr contains the standard error output from the function execution + Stderr string `json:"stderr,omitempty"` + + // ExitCode is the exit code returned by the function + ExitCode int `json:"exitCode"` + + // Results contains successful results from the function + Results []ResultItem `json:"results,omitempty"` + + // ErrorResults contains error results from the function + ErrorResults []ResultItem `json:"errorResults,omitempty"` +} + +// ResultItem represents a single result item from a function execution +type ResultItem struct { + // Resource is the KRM resource that was processed (serialized as YAML string) + Resource string `json:"resource,omitempty"` + + // Message contains details about the result + Message string `json:"message,omitempty"` + + // Severity indicates the severity level of the result (error, warning, info) + Severity string `json:"severity,omitempty"` +} From 0cad1cbde40c0ff9ca160d77b5f5c38de8e7f329 Mon Sep 17 00:00:00 2001 From: NETIZEN-11 Date: Thu, 19 Mar 2026 12:03:25 +0530 Subject: [PATCH 4/6] fix: resolve CI failures by fixing wasmtime Windows linking and linting issues - Add Windows build constraints to exclude wasmtime support - Fix linting issues: spelling, unused parameters, unused functions - Use errors.New for static error strings - Remove unused setRenderCondition function This resolves the failing CI checks for docker and podman builds. --- internal/fnruntime/wasmtime.go | 2 +- internal/fnruntime/wasmtime_unsupported.go | 14 +++++++------- internal/util/render/executor.go | 5 ----- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/internal/fnruntime/wasmtime.go b/internal/fnruntime/wasmtime.go index 1537549082..707defbcce 100644 --- a/internal/fnruntime/wasmtime.go +++ b/internal/fnruntime/wasmtime.go @@ -1,4 +1,4 @@ -//go:build cgo +//go:build cgo && !windows // Copyright 2022,2026 The kpt Authors // diff --git a/internal/fnruntime/wasmtime_unsupported.go b/internal/fnruntime/wasmtime_unsupported.go index ba52f8927c..d325d6456f 100644 --- a/internal/fnruntime/wasmtime_unsupported.go +++ b/internal/fnruntime/wasmtime_unsupported.go @@ -1,4 +1,4 @@ -//go:build !cgo +//go:build !cgo || windows // Copyright 2022,2026 The kpt Authors // @@ -20,21 +20,21 @@ package fnruntime // wasmtime requires cgo, which is not always a viable option. import ( - "fmt" + "errors" "io" ) const ( - msg = "wasmtime support is not complied into this binary. Binaries with wasmtime is avilable at github.com/kptdev/kpt" + msg = "wasmtime support is not compiled into this binary. Binaries with wasmtime are available at github.com/kptdev/kpt" ) type WasmtimeFn struct { } -func NewWasmtimeFn(loader WasmLoader) (*WasmtimeFn, error) { - return nil, fmt.Errorf(msg) +func NewWasmtimeFn(_ WasmLoader) (*WasmtimeFn, error) { + return nil, errors.New(msg) } -func (f *WasmtimeFn) Run(r io.Reader, w io.Writer) error { - return fmt.Errorf(msg) +func (f *WasmtimeFn) Run(_ io.Reader, _ io.Writer) error { + return errors.New(msg) } diff --git a/internal/util/render/executor.go b/internal/util/render/executor.go index 787fd95f67..3ccb0a009a 100644 --- a/internal/util/render/executor.go +++ b/internal/util/render/executor.go @@ -244,11 +244,6 @@ func updateRenderStatus(hctx *hydrationContext, hydErr error) { setRenderConditionWithStatus(hctx.fileSystem, rootPath, kptfilev1.NewRenderedCondition(conditionStatus, reason, message), hctx.renderStatus) } -// setRenderCondition reads the Kptfile at pkgPath, sets the Rendered condition, and writes it back. -func setRenderCondition(fs filesys.FileSystem, pkgPath string, condition kptfilev1.Condition) { - setRenderConditionWithStatus(fs, pkgPath, condition, nil) -} - // setRenderConditionWithStatus reads the Kptfile at pkgPath, sets the Rendered condition and RenderStatus, and writes it back. func setRenderConditionWithStatus(fs filesys.FileSystem, pkgPath string, condition kptfilev1.Condition, renderStatus *kptfilev1.RenderStatus) { fsOrDisk := filesys.FileSystemOrOnDisk{FileSystem: fs} From 45cf0a117947178e984fdb1e1dc7c2eaba80b93d Mon Sep 17 00:00:00 2001 From: Nitesh Date: Fri, 20 Mar 2026 00:33:13 +0530 Subject: [PATCH 5/6] Fix Kubernetes dependencies and render status implementation - Update k8s.io/apiextensions-apiserver from v0.34.1 to v0.35.0 - Add yaml tags to RenderStatus, PipelineStepResult, and ResultItem structs - Fix result classification logic to use severity instead of ExitCode - Fix YAML test input to use proper multiline format - Run go mod tidy to normalize dependencies All changes maintain Go formatting and project coding style. --- go.mod | 3 +-- go.sum | 35 ++------------------------- internal/util/render/executor.go | 9 ++++--- internal/util/render/executor_test.go | 7 +++++- pkg/api/kptfile/v1/types.go | 28 ++++++++++----------- 5 files changed, 28 insertions(+), 54 deletions(-) diff --git a/go.mod b/go.mod index e0b28c8902..87a713f128 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( gopkg.in/yaml.v2 v2.4.0 gotest.tools v2.2.0+incompatible k8s.io/api v0.35.0 - k8s.io/apiextensions-apiserver v0.34.1 + k8s.io/apiextensions-apiserver v0.35.0 k8s.io/apimachinery v0.35.0 k8s.io/cli-runtime v0.35.0 k8s.io/client-go v0.35.0 @@ -75,7 +75,6 @@ require ( github.com/go-openapi/swag/stringutils v0.25.1 // indirect github.com/go-openapi/swag/typeutils v0.25.1 // indirect github.com/go-openapi/swag/yamlutils v0.25.1 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/gnostic-models v0.7.0 // indirect github.com/google/uuid v1.6.0 // indirect diff --git a/go.sum b/go.sum index 86f23cbfa7..5542d3305d 100644 --- a/go.sum +++ b/go.sum @@ -83,8 +83,6 @@ github.com/go-openapi/swag/yamlutils v0.25.1 h1:mry5ez8joJwzvMbaTGLhw8pXUnhDK91o github.com/go-openapi/swag/yamlutils v0.25.1/go.mod h1:cm9ywbzncy3y6uPm/97ysW8+wZ09qsks+9RS8fLWKqg= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= @@ -108,8 +106,6 @@ github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbd github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/kptdev/krm-functions-catalog/functions/go/apply-setters v0.2.4 h1:qB0Az/M+qo31s5RD3YXV0bUkTKZ3I19Kdji42cFSPHY= @@ -212,8 +208,6 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= @@ -228,51 +222,26 @@ go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -295,8 +264,8 @@ gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= k8s.io/api v0.35.0 h1:iBAU5LTyBI9vw3L5glmat1njFK34srdLmktWwLTprlY= k8s.io/api v0.35.0/go.mod h1:AQ0SNTzm4ZAczM03QH42c7l3bih1TbAXYo0DkF8ktnA= -k8s.io/apiextensions-apiserver v0.34.1 h1:NNPBva8FNAPt1iSVwIE0FsdrVriRXMsaWFMqJbII2CI= -k8s.io/apiextensions-apiserver v0.34.1/go.mod h1:hP9Rld3zF5Ay2Of3BeEpLAToP+l4s5UlxiHfqRaRcMc= +k8s.io/apiextensions-apiserver v0.35.0 h1:3xHk2rTOdWXXJM+RDQZJvdx0yEOgC0FgQ1PlJatA5T4= +k8s.io/apiextensions-apiserver v0.35.0/go.mod h1:E1Ahk9SADaLQ4qtzYFkwUqusXTcaV2uw3l14aqpL2LU= k8s.io/apimachinery v0.35.0 h1:Z2L3IHvPVv/MJ7xRxHEtk6GoJElaAqDCCU0S6ncYok8= k8s.io/apimachinery v0.35.0/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= k8s.io/cli-runtime v0.35.0 h1:PEJtYS/Zr4p20PfZSLCbY6YvaoLrfByd6THQzPworUE= diff --git a/internal/util/render/executor.go b/internal/util/render/executor.go index 3ccb0a009a..71d5f81281 100644 --- a/internal/util/render/executor.go +++ b/internal/util/render/executor.go @@ -379,7 +379,7 @@ func createResultItem(resource *yaml.RNode, message, severity string) kptfilev1. // extractResultsFromFnResults extracts and categorizes results from function execution. // It processes framework.Results and converts them to ResultItem instances, -// separating successful results from error results based on exit codes. +// separating successful results from error results based on severity. func extractResultsFromFnResults(fnResults *fnresult.ResultList) ([]kptfilev1.ResultItem, []kptfilev1.ResultItem) { var results []kptfilev1.ResultItem var errorResults []kptfilev1.ResultItem @@ -405,10 +405,11 @@ func extractResultsFromFnResults(fnResults *fnresult.ResultList) ([]kptfilev1.Re resultItem := createResultItem(nil, message, severity) - if item.ExitCode == 0 { - results = append(results, resultItem) - } else { + // Classify based on severity instead of ExitCode + if severity == "error" { errorResults = append(errorResults, resultItem) + } else { + results = append(results, resultItem) } } } diff --git a/internal/util/render/executor_test.go b/internal/util/render/executor_test.go index cae2860e6d..992f976033 100644 --- a/internal/util/render/executor_test.go +++ b/internal/util/render/executor_test.go @@ -812,7 +812,12 @@ func TestCreateResultItem(t *testing.T) { assert.Empty(t, result.Resource) // Test with resource - resource := yaml.MustParse(`apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: test`) + resource := yaml.MustParse(` +apiVersion: v1 +kind: ConfigMap +metadata: + name: test +`) resultWithResource := createResultItem(resource, "resource processed", "info") assert.Equal(t, "resource processed", resultWithResource.Message) assert.Equal(t, "info", resultWithResource.Severity) diff --git a/pkg/api/kptfile/v1/types.go b/pkg/api/kptfile/v1/types.go index 630f0cdcda..99f503bfec 100644 --- a/pkg/api/kptfile/v1/types.go +++ b/pkg/api/kptfile/v1/types.go @@ -476,50 +476,50 @@ func ToCondition(value string) ConditionStatus { // RenderStatus contains detailed information about pipeline execution results type RenderStatus struct { // MutationSteps contains results from mutation pipeline functions - MutationSteps []PipelineStepResult `json:"mutationSteps,omitempty"` + MutationSteps []PipelineStepResult `yaml:"mutationSteps,omitempty" json:"mutationSteps,omitempty"` // ValidationSteps contains results from validation pipeline functions - ValidationSteps []PipelineStepResult `json:"validationSteps,omitempty"` + ValidationSteps []PipelineStepResult `yaml:"validationSteps,omitempty" json:"validationSteps,omitempty"` // ErrorSummary provides a consolidated summary of all errors - ErrorSummary string `json:"errorSummary,omitempty"` + ErrorSummary string `yaml:"errorSummary,omitempty" json:"errorSummary,omitempty"` } // PipelineStepResult contains the result of executing a single pipeline step type PipelineStepResult struct { // Name is the name of the function step - Name string `json:"name,omitempty"` + Name string `yaml:"name,omitempty" json:"name,omitempty"` // Image is the container image that was executed - Image string `json:"image,omitempty"` + Image string `yaml:"image,omitempty" json:"image,omitempty"` // ExecPath is the executable path that was run - ExecPath string `json:"execPath,omitempty"` + ExecPath string `yaml:"execPath,omitempty" json:"execPath,omitempty"` // ExecutionError captures execution failures like network errors, missing images, etc. - ExecutionError string `json:"executionError,omitempty"` + ExecutionError string `yaml:"executionError,omitempty" json:"executionError,omitempty"` // Stderr contains the standard error output from the function execution - Stderr string `json:"stderr,omitempty"` + Stderr string `yaml:"stderr,omitempty" json:"stderr,omitempty"` // ExitCode is the exit code returned by the function - ExitCode int `json:"exitCode"` + ExitCode int `yaml:"exitCode" json:"exitCode"` // Results contains successful results from the function - Results []ResultItem `json:"results,omitempty"` + Results []ResultItem `yaml:"results,omitempty" json:"results,omitempty"` // ErrorResults contains error results from the function - ErrorResults []ResultItem `json:"errorResults,omitempty"` + ErrorResults []ResultItem `yaml:"errorResults,omitempty" json:"errorResults,omitempty"` } // ResultItem represents a single result item from a function execution type ResultItem struct { // Resource is the KRM resource that was processed (serialized as YAML string) - Resource string `json:"resource,omitempty"` + Resource string `yaml:"resource,omitempty" json:"resource,omitempty"` // Message contains details about the result - Message string `json:"message,omitempty"` + Message string `yaml:"message,omitempty" json:"message,omitempty"` // Severity indicates the severity level of the result (error, warning, info) - Severity string `json:"severity,omitempty"` + Severity string `yaml:"severity,omitempty" json:"severity,omitempty"` } From fb987aff55ef47428f969aeb1315349d68a2ef32 Mon Sep 17 00:00:00 2001 From: NETIZEN-11 Date: Fri, 20 Mar 2026 01:21:12 +0530 Subject: [PATCH 6/6] Fix GitHub Issue #4333: Improve handling of package context in subpackages - Add isRootKptfile() helper function for robust root detection - Enhance pkgContextResource() to generate package-context.yaml only for root packages - Subpackages are now correctly suppressed to prevent duplicate ConfigMap creation - Fix path normalization to handle relative paths like './Kptfile' - Ensure only one ConfigMap 'kptfile.kpt.dev' exists in mutation pipeline This resolves the 'ConfigMap already exists' error when rendering packages with subpackages. --- internal/builtins/pkg_context.go | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/internal/builtins/pkg_context.go b/internal/builtins/pkg_context.go index 80d74df606..3c7048bab5 100644 --- a/internal/builtins/pkg_context.go +++ b/internal/builtins/pkg_context.go @@ -34,6 +34,13 @@ var ( kptfileGVK = resid.NewGvk(kptfilev1.KptFileGVK().Group, kptfilev1.KptFileGVK().Version, kptfilev1.KptFileGVK().Kind) ) +// isRootKptfile checks if the given path represents a root Kptfile +func isRootKptfile(kptfilePath string) bool { + cleanPath := path.Clean(kptfilePath) + base := path.Base(cleanPath) + return base == kptfilev1.KptFileGVK().Kind +} + // PackageContextGenerator is a built-in KRM function that generates // a KRM object that contains package context information that can be // used by functions such as `set-namespace` to customize package with @@ -115,13 +122,23 @@ func pkgContextResource(kptfile *yaml.RNode, packageConfig *builtintypes.Package return nil, err } - // We only want one "package-context.yaml" in each kpt package - if kptfilePath != kptfilev1.KptFileGVK().Kind { + // We only want one "package-context.yaml" in the root kpt package + // Root package has Kptfile at the root path (no subdirectories), while subpackages + // will have paths like "subpkg/Kptfile" + // Normalize the path first to handle relative paths like "./Kptfile" + cleanPath := path.Clean(kptfilePath) + if !isRootKptfile(cleanPath) { + return nil, nil + } + + // Check if this is the root package by verifying the Kptfile is at the root level + if path.Dir(cleanPath) != "." { + // This is a subpackage, don't generate package context return nil, nil } annotations := map[string]string{ - kioutil.PathAnnotation: path.Join(path.Dir(kptfilePath), builtintypes.PkgContextFile), + kioutil.PathAnnotation: path.Join(path.Dir(cleanPath), builtintypes.PkgContextFile), } for k, v := range annotations {