Skip to content

fix(update): preserve Kptfile formatting during upgrades#4427

Open
Jaisheesh-2006 wants to merge 7 commits intokptdev:mainfrom
Jaisheesh-2006:fix/4306-prevent-kptfile-upgrade
Open

fix(update): preserve Kptfile formatting during upgrades#4427
Jaisheesh-2006 wants to merge 7 commits intokptdev:mainfrom
Jaisheesh-2006:fix/4306-prevent-kptfile-upgrade

Conversation

@Jaisheesh-2006
Copy link
Copy Markdown
Contributor

Description

This PR fixes Kptfile formatting drift during package upgrades by switching upgrade-time Kptfile handling to an SDK-backed read/update flow and removing legacy rewrite logic from kptops helpers.

Motivation

During kpt pkg update, Kptfile rewrites could alter user formatting/comments in ways that were not intended.
Issue #4306 tracks this regression and expects upgrade behavior to preserve user-authored Kptfile structure as much as possible.

What Changed

  • Refactored upgrade-path Kptfile read/update operations to use SDK-backed Kptfile handling in kptfileutil.
  • Removed legacy custom Kptfile rewrite behavior in pkg/lib/kptops helper flows, reusing the centralized updater.
  • Hardened tests for cross-platform consistency:
    • line ending normalization where needed
    • environment-aware symlink assertions
    • Kptfile-focused preservation coverage

Scope

This change targets upgrade and related Kptfile mutation paths only, with no intended functional change to unrelated package/resource update behavior.

Testing

Validated with targeted and package-level tests, including:

  • go test ./pkg/kptfile/... -count=1
  • go test ./pkg/lib/kptops -count=1
  • go test ./commands/pkg/update -count=1
  • go test ./internal/util/update/... -count=1

Issue

Fixes #4306

Copilot AI review requested due to automatic review settings March 6, 2026 07:09
@netlify
Copy link
Copy Markdown

netlify bot commented Mar 6, 2026

Deploy Preview for kptdocs ready!

Name Link
🔨 Latest commit f536bb8
🔍 Latest deploy log https://app.netlify.com/projects/kptdocs/deploys/69d6abeae22d870008de5728
😎 Deploy Preview https://deploy-preview-4427--kptdocs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. bug Something isn't working go Pull requests that update Go code labels Mar 6, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses Kptfile formatting/comment drift during kpt pkg update by switching upgrade-time Kptfile mutations to an SDK-backed read/modify/write flow intended to preserve YAML structure and comments.

Changes:

  • Refactors kptops Kptfile update helpers to use kptfileutil.UpdateKptfileContent rather than re-marshalling via kyaml.
  • Adds SDK-based Kptfile write/update logic in kptfileutil to better preserve formatting/comments.
  • Hardens tests for cross-platform behavior (CRLF normalization, environment-aware symlink assertions) and adds Kptfile preservation coverage.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
pkg/lib/kptops/render_test.go Normalizes CRLF/LF in golden comparisons to reduce cross-platform diffs.
pkg/lib/kptops/clone_test.go Adds tests asserting UpdateUpstream/UpdateName preserve comments/formatting.
pkg/lib/kptops/clone.go Routes Kptfile mutations through kptfileutil.UpdateKptfileContent to preserve formatting.
pkg/kptfile/kptfileutil/util_test.go Adds tests for comment/format preservation during UpdateKptfile.
pkg/kptfile/kptfileutil/util.go Introduces SDK-based Kptfile write/update utilities and updates decode flow.
internal/util/get/get_test.go Makes symlink assertions conditional on whether symlinks materialize in the test environment.
internal/builtins/pkg_context_test.go Normalizes CRLF/LF for deterministic output comparison.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Jaisheesh-2006 Jaisheesh-2006 force-pushed the fix/4306-prevent-kptfile-upgrade branch from e6f980d to ffd9c47 Compare March 6, 2026 07:52
Copilot AI review requested due to automatic review settings March 6, 2026 09:59
@Jaisheesh-2006 Jaisheesh-2006 force-pushed the fix/4306-prevent-kptfile-upgrade branch from ffd9c47 to a4335c5 Compare March 6, 2026 09:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings April 8, 2026 16:15
@Jaisheesh-2006 Jaisheesh-2006 force-pushed the fix/4306-prevent-kptfile-upgrade branch from 5f117d1 to d622237 Compare April 8, 2026 16:15
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings April 8, 2026 16:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Jaisheesh-2006 and others added 6 commits April 9, 2026 00:45
Use SDK-backed Kptfile read/update flow in upgrade paths, remove legacy rewrite behavior from kptops helpers, and harden tests for cross-platform stability.

Fixes kptdev#4306

Signed-off-by: Jaisheesh-2006 <jaicodes2006@gmail.com>
Reuse DecodeKptfile validation in UpdateKptfileContent so invalid,
deprecated, or unknown-field Kptfiles fail before SDK processing.

Strip SDK-internal metadata annotations before applying mutations to
avoid writing internal config.kubernetes.io fields back to user
Kptfiles.

Add regression tests covering validation parity, annotation stripping,
empty annotation cleanup, and nil-safe handling.

Signed-off-by: Jaisheesh-2006 <jaicodes2006@gmail.com>
Signed-off-by: Jaisheesh-2006 <jaicodes2006@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Jaisheesh-2006 <jaicodes2006@gmail.com>
…ly expectation

Signed-off-by: Jaisheesh-2006 <jaicodes2006@gmail.com>
Signed-off-by: Jaisheesh-2006 <jaicodes2006@gmail.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…Kptfile

Signed-off-by: Jaisheesh-2006 <jaicodes2006@gmail.com>
Comment on lines +344 to +349
if !assert.NoError(t, err) {
return
}
if !assert.NotNil(t, fnResults) {
return
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what you want here is require.NoError and require.NotNil instead.

name: root-package
annotations:
kpt.dev/bfs-rendering: %t
kpt.dev/bfs-rendering: "%t"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch!

Comment on lines +447 to +449
if !assert.NoError(t, err) {
return
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if !assert.NoError(t, err) {
return
}
require.NoError(t, err)

Comment on lines +91 to +103
if kf, ok := k.(*kptfilev1.KptFile); ok {
if err := writeKptfilePreservingFormat(dir, kf); err != nil {
return errors.E(op, types.UniquePath(dir), err)
}
return nil
}

if kf, ok := k.(kptfilev1.KptFile); ok {
if err := writeKptfilePreservingFormat(dir, &kf); err != nil {
return errors.E(op, types.UniquePath(dir), err)
}
return nil
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this look better in a switch statement? (actual question, not suggestion)

Something like:

switch k.(type) {
case *kptfilev1.Kptfile:
	...
case kptfilev1.Kptfile:
	...
}

return nil
}

func applyTypedKptfileToSDK(sdkKptfile *kptfileko.KptfileKubeObject, desired *kptfilev1.KptFile) error {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
func applyTypedKptfileToSDK(sdkKptfile *kptfileko.KptfileKubeObject, desired *kptfilev1.KptFile) error {
func applyTypedKptfileToKubeObject(sdkKptfile *kptfileko.KptfileKubeObject, desired *kptfilev1.KptFile) error {

Comment on lines +26 to +32
func normalizeLineEndings(s string) string {
return strings.ReplaceAll(s, "\r\n", "\n")
}

func normalizeAndTrim(s string) string {
return strings.TrimSpace(normalizeLineEndings(s))
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could probably move these to a more central place and use them elsewhere

Comment on lines +66 to +67
expected := strings.ReplaceAll(string(exp), "\r\n", "\n")
actual := strings.ReplaceAll(out.String(), "\r\n", "\n")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use that normalizeLineEndings function here

Comment on lines +81 to +82
got := strings.ReplaceAll(output.String(), "\r\n", "\n")
want := strings.ReplaceAll(string(readFile(t, filepath.Join(testdata, test.name, test.want))), "\r\n", "\n")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use that normalizeLineEndings function here

Comment on lines +600 to +602
if !assert.NoError(t, err) {
t.FailNow()
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see a lot of these, please use require.NoError instead

Comment on lines +616 to +623
writeKptfileToTemp := func(tt *testing.T, content string) string {
dir := tt.TempDir()
err := os.WriteFile(filepath.Join(dir, kptfilev1.KptFileName), []byte(content), 0600)
if !assert.NoError(tt, err) {
tt.FailNow()
}
return dir
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a bit of an overcomplication. Just have function like this in global scope:

writeKptfileToTemp(t *testing.T, content string) string {
	t.Helper()
	dir := t.TempDir()
	err := os.WriteFile(filepath.Join(dir, kptfilev1.KptFileName), []byte(content), 0600)
	require.NoError(t, err)
	return dir
}

And reuse it wherever.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working go Pull requests that update Go code size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prevent formatting the kptfile during upgrades

3 participants