From 4eb598f96aa53d1c0b8234af2087834e1f2275e1 Mon Sep 17 00:00:00 2001 From: Ahmed AbouZaid <6760103+aabouzaid@users.noreply.github.com> Date: Thu, 28 Oct 2021 14:29:56 +0200 Subject: [PATCH] feat: support chart release-notes or changelog (#137) * feat: support chart release-notes or changelog Signed-off-by: Ahmed AbouZaid * add docs and unit tests for chart release-notes option Signed-off-by: Ahmed AbouZaid --- README.md | 1 + cr/cmd/upload.go | 2 + pkg/config/config.go | 1 + pkg/releaser/releaser.go | 14 ++++- pkg/releaser/releaser_test.go | 52 ++++++++++++++++++ .../release-packages/test-chart-0.1.0.tgz | Bin 645 -> 679 bytes 6 files changed, 69 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a9c04fc..1e0ce202 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ Flags: -o, --owner string GitHub username or organization -p, --package-path string Path to directory with chart packages (default ".cr-release-packages") --release-name-template string Go template for computing release names, using chart metadata (default "{{ .Name }}-{{ .Version }}") + --release-notes-file string Markdown file with chart release notes. If it is set to empty string, or the file is not found, the chart description will be used instead --skip-existing Skip upload if release exists -t, --token string GitHub Auth Token diff --git a/cr/cmd/upload.go b/cr/cmd/upload.go index 492a45be..b61f1bda 100644 --- a/cr/cmd/upload.go +++ b/cr/cmd/upload.go @@ -53,4 +53,6 @@ func init() { uploadCmd.Flags().StringP("commit", "c", "", "Target commit for release") uploadCmd.Flags().Bool("skip-existing", false, "Skip upload if release exists") uploadCmd.Flags().String("release-name-template", "{{ .Name }}-{{ .Version }}", "Go template for computing release names, using chart metadata") + uploadCmd.Flags().String("release-notes-file", "", "Markdown file with chart release notes. "+ + "If it is set to empty string, or the file is not found, the chart description will be used instead") } diff --git a/pkg/config/config.go b/pkg/config/config.go index 79ae19a0..982af1cb 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -57,6 +57,7 @@ type Options struct { Remote string `mapstructure:"remote"` ReleaseNameTemplate string `mapstructure:"release-name-template"` SkipExisting bool `mapstructure:"skip-existing"` + ReleaseNotesFile string `mapstructure:"release-notes-file"` } func LoadConfiguration(cfgFile string, cmd *cobra.Command, requiredFlags []string) (*Options, error) { diff --git a/pkg/releaser/releaser.go b/pkg/releaser/releaser.go index a9cda00b..cae08aab 100644 --- a/pkg/releaser/releaser.go +++ b/pkg/releaser/releaser.go @@ -263,6 +263,17 @@ func (r *Releaser) computeReleaseName(chart *chart.Chart) (string, error) { return releaseName, nil } +func (r *Releaser) getReleaseNotes(chart *chart.Chart) string { + if r.config.ReleaseNotesFile != "" { + for _, f := range chart.Files { + if f.Name == r.config.ReleaseNotesFile { + return string(f.Data) + } + } + } + return chart.Metadata.Description +} + func (r *Releaser) splitPackageNameAndVersion(pkg string) []string { delimIndex := strings.LastIndex(pkg, "-") return []string{pkg[0:delimIndex], pkg[delimIndex+1:]} @@ -317,9 +328,10 @@ func (r *Releaser) CreateReleases() error { if err != nil { return err } + release := &github.Release{ Name: releaseName, - Description: ch.Metadata.Description, + Description: r.getReleaseNotes(ch), Assets: []*github.Asset{ {Path: p}, }, diff --git a/pkg/releaser/releaser_test.go b/pkg/releaser/releaser_test.go index 6df6ec12..1f1c0aa9 100644 --- a/pkg/releaser/releaser_test.go +++ b/pkg/releaser/releaser_test.go @@ -311,3 +311,55 @@ func TestReleaser_CreateReleases(t *testing.T) { }) } } + +func TestReleaser_ReleaseNotes(t *testing.T) { + tests := []struct { + name string + packagePath string + chart string + version string + releaseNotesFile string + expectedReleaseNotes string + }{ + { + "chart-package-with-release-notes-file", + "testdata/release-packages", + "test-chart", + "0.1.0", + "release-notes.md", + "The release notes file content is used as release notes", + }, + { + "chart-package-with-non-exists-release-notes-file", + "testdata/release-packages", + "test-chart", + "0.1.0", + "non-exists-release-notes.md", + "A Helm chart for Kubernetes", + }, + { + "chart-package-with-empty-release-notes-file-config-value", + "testdata/release-packages", + "test-chart", + "0.1.0", + "", + "A Helm chart for Kubernetes", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fakeGitHub := new(FakeGitHub) + r := &Releaser{ + config: &config.Options{ + PackagePath: "testdata/release-packages", + ReleaseNotesFile: tt.releaseNotesFile, + }, + github: fakeGitHub, + } + fakeGitHub.On("CreateRelease", mock.Anything, mock.Anything).Return(nil) + err := r.CreateReleases() + assert.NoError(t, err) + assert.Equal(t, tt.expectedReleaseNotes, fakeGitHub.release.Description) + }) + } +} diff --git a/pkg/releaser/testdata/release-packages/test-chart-0.1.0.tgz b/pkg/releaser/testdata/release-packages/test-chart-0.1.0.tgz index 9b2b29c84f949b9309fc655f17e807430de01ccc..9ba6d6c3a77a15c8d1eb7dd54eb09d4fa1f366da 100644 GIT binary patch literal 679 zcmV;Y0$BYYiwFS2t#n}k1MODZYTG~%&9lB@5Dl~`mL*$~!H|cN7Fr4^G$nluYiU$3 ztS;SMr7>y#y|XJtz7QudaT5YM57K%)o;h>3Mx_VIoJl=AF;8#7a&fR<_`W}hA~0{l z=G*s!XavDH3@2e2OeQ1ngYhVg4#3|tk2_H-%_LEIs-8{fUI|#m&rvE~7E`zk99C7` zM>p_%*GW+&l2_VZeSps>aV zoKvIAJ7=OsWhKAS;E+5;_zPOrMFR2I9(jINXBoc&cd%53#K@c*iYF4OfPr;3vRa4* z{H~ec8OIc8zFG2~^Aj8GR$dz$hO2@ZCahKnsw7&=@z%IZIz*~~Nd&=ju1TXVDGFS{ z+u6c~k>$lNP!%TcJm*UW5(P5V#w{re&3K{OF>3F)hCf^gvJPaNc#;uIzGZt~ zbdA`0gn8Bl^!CdxsJAj(1s)Z3p_ZE7SP!Phk5B9h&n_5^7Vmo#spiKW*R|W7309I9 zIs^Am4GxvNp{=pIOQ~%;ua)3RZcWp)yU^s-=C>`DMoO?5iu-eHpYB$VRs-Ig+bvGs zNTjKrkh=FSxEJnDuDhZs^vj5v5H7H8D^zw9XHfSHlacEX!Fp2!tcZ+xeK^Tmq zU=+u8|I_-9pLzeYd5-tF{LuHWbpQXLDb#HzlX&|dz>Z}sG;r1Jqcy3Qrro1Qj~+dq Nh=06*4dwt8006wENTdJ& literal 645 zcmV;00($))iwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PIy=Yuhjs&9i^SMXa!OM3M6efj*3GurcUhh3>H^_SGVgWlfT^ zhPMBGNOqkxv|Yopm4VNLttiJ==N{cFd33&?ExGlB)9|EgUZ~z-!5Cw+$t1oRW4mvb zPKLd7G#<~!<8(F~_EGPL_HOt2E)pv_DBo z8A)<A}quw0iEci|T57}tC)Bls{bkz0#zrgkN;22i2n1e$PLMrrYgC|9>C0pVg zjt955Nnj-(t_;^X_$5NO78XiKiC1N8s%mqEc!NKPs-IkeCBE zCW@!YH>{&az7J~ztqvBL@ya2%vcRq5txj1;RJj9g5tJ;X#~geKekmQiUaX@X@6XNy zSL*NJ3}$a=@=1V2h1@m1Wu^99YS$d2aZY;pDV2f+Lgj)^2Rw>z)IQ~Ipxt*^iq_D( zKU-7pIFAyZ<+^g4NUvfB^ONUq?3T{fj5-SaT02#L+-kiyySG4NrS<~Ik?S8hvJ-B9eU1Cu6idxge1YoeJ&sTEXhz$H*W>0Eha0eH6weUITLR>g f?3L