From 0623915bb987d817aa5a6403073988fe89e1be3a Mon Sep 17 00:00:00 2001 From: Sascha Grunert Date: Tue, 2 Apr 2024 12:16:13 +0200 Subject: [PATCH] Compare original PR body on release notes mapping When creating a mapping we now preserve the original PR body in the YAML map. This allows us to track modifications to the PR if their values already got mapped during the release cycle and warn the end user in that case. Fixes https://github.com/kubernetes/release/issues/3510 Signed-off-by: Sascha Grunert --- cmd/krel/cmd/release_notes.go | 5 ++++- pkg/notes/notes.go | 15 +++++++++++++++ pkg/notes/notes_map.go | 3 +++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/cmd/krel/cmd/release_notes.go b/cmd/krel/cmd/release_notes.go index c2eb2bdcca5a..475bdd2a2f13 100644 --- a/cmd/krel/cmd/release_notes.go +++ b/cmd/krel/cmd/release_notes.go @@ -400,7 +400,7 @@ func createDraftPR(repoPath, tag string) (err error) { } // Run the release notes fix flow - err := fixReleaseNotes(filepath.Join(releaseDir, releaseNotesWorkDir), releaseNotes) + err := FixReleaseNotes(filepath.Join(releaseDir, releaseNotesWorkDir), releaseNotes) if err != nil { return fmt.Errorf("while running release notes fix flow: %w", err) } @@ -1154,6 +1154,7 @@ func fixReleaseNotes(workDir string, releaseNotes *notes.ReleaseNotes) error { ActionRequired: note.ActionRequired, Documentation: note.Documentation, DoNotPublish: note.DoNotPublish, + PRBody: note.PRBody, } if noteMaps != nil { @@ -1410,6 +1411,8 @@ func editReleaseNote(pr int, workDir string, originalNote, modifiedNote *notes.R return true, errors.New("invalid map: the YAML code did not have a PR number") } + testMap.PRBody = &originalNote.PRBody + // Remarshall the newyaml to save only the new values newYAML, err := yaml.Marshal(testMap) if err != nil { diff --git a/pkg/notes/notes.go b/pkg/notes/notes.go index 831b0c78d020..184fed744601 100644 --- a/pkg/notes/notes.go +++ b/pkg/notes/notes.go @@ -37,6 +37,7 @@ import ( gogithub "github.com/google/go-github/v58/github" "github.com/nozzle/throttler" + "github.com/sergi/go-diff/diffmatchpatch" "github.com/sirupsen/logrus" "golang.org/x/text/cases" "golang.org/x/text/language" @@ -139,6 +140,9 @@ type ReleaseNote struct { // IsMapped is set if the note got modified from a map IsMapped bool `json:"is_mapped,omitempty"` + + // PRBody is the full PR body of the release note + PRBody string `json:"pr_body,omitempty"` } type Documentation struct { @@ -518,6 +522,7 @@ func (g *Gatherer) ReleaseNoteFromCommit(result *Result) (*ReleaseNote, error) { DuplicateKind: isDuplicateKind, ActionRequired: labelExactMatch(pr, "release-note-action-required"), DoNotPublish: labelExactMatch(pr, "release-note-none"), + PRBody: prBody, }, nil } @@ -757,6 +762,7 @@ func (g *Gatherer) ReleaseNoteForPullRequest(prNr int) (*ReleaseNote, error) { ActionRequired: false, DoNotPublish: doNotPublish, DataFields: map[string]ReleaseNotesDataField{}, + PRBody: prBody, } if s != "" { @@ -1151,6 +1157,14 @@ func (rn *ReleaseNote) ApplyMap(noteMap *ReleaseNotesMap, markdownLinks bool) er }).Debugf("Applying map to note") rn.IsMapped = true + if noteMap.PRBody != nil && rn.PRBody != "" && rn.PRBody != *noteMap.PRBody { + logrus.Warnf("Original PR body of release note mapping changed for PR: #%d", rn.PrNumber) + + dmp := diffmatchpatch.New() + diffs := dmp.DiffMain(rn.PRBody, *noteMap.PRBody, false) + logrus.Warnf("The diff between actual release note body and mapped one is:\n%s", dmp.DiffPrettyText(diffs)) + } + reRenderMarkdown := false if noteMap.ReleaseNote.Author != nil { rn.Author = *noteMap.ReleaseNote.Author @@ -1231,6 +1245,7 @@ func (rn *ReleaseNote) ToNoteMap() (string, error) { noteMap.ReleaseNote.Feature = &rn.Feature noteMap.ReleaseNote.ActionRequired = &rn.ActionRequired noteMap.ReleaseNote.DoNotPublish = &rn.DoNotPublish + noteMap.PRBody = &rn.PRBody yamlCode, err := yaml.Marshal(¬eMap) if err != nil { diff --git a/pkg/notes/notes_map.go b/pkg/notes/notes_map.go index a08c42479019..066e56767501 100644 --- a/pkg/notes/notes_map.go +++ b/pkg/notes/notes_map.go @@ -117,6 +117,9 @@ type ReleaseNotesMap struct { } `json:"releasenote"` DataFields map[string]ReleaseNotesDataField `json:"datafields,omitempty" yaml:"datafields,omitempty"` + + // PRBody is the full original PR body. + PRBody *string `json:"pr_body,omitempty" yaml:"pr_body,omitempty"` } // ReleaseNotesDataField extra data added to a release note