Skip to content

Commit 0dcc281

Browse files
authored
Merge pull request #3580 from embik/fix-3565
Refactor `pkg/announce` package into sub-packages and interface pattern
2 parents 9f115b6 + c7379a7 commit 0dcc281

File tree

16 files changed

+1676
-663
lines changed

16 files changed

+1676
-663
lines changed

cmd/publish-release/cmd/github.go

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ import (
3131
"github.com/sirupsen/logrus"
3232
"github.com/spf13/cobra"
3333
"google.golang.org/api/option"
34-
"k8s.io/release/pkg/announce"
34+
"k8s.io/release/pkg/announce/github"
35+
"k8s.io/release/pkg/announce/sbom"
3536
)
3637

3738
// releaseNotesCmd represents the subcommand for `krel release-notes`
@@ -154,7 +155,7 @@ func init() {
154155
githubPageCmd.PersistentFlags().StringVar(
155156
&ghPageOpts.sbomFormat,
156157
"sbom-format",
157-
string(announce.FormatJSON),
158+
string(sbom.FormatJSON),
158159
"format to use for the SBOM [json|tag-value]",
159160
)
160161
githubPageCmd.PersistentFlags().StringVar(
@@ -183,8 +184,8 @@ func init() {
183184
rootCmd.AddCommand(githubPageCmd)
184185
}
185186

186-
func getAssetsFromStrings(assetStrings []string) ([]announce.Asset, error) {
187-
r := []announce.Asset{}
187+
func getAssetsFromStrings(assetStrings []string) ([]sbom.Asset, error) {
188+
r := []sbom.Asset{}
188189
var isBucket bool
189190
for _, s := range assetStrings {
190191
isBucket = false
@@ -205,7 +206,7 @@ func getAssetsFromStrings(assetStrings []string) ([]announce.Asset, error) {
205206
}
206207
parts[0] = path
207208
}
208-
r = append(r, announce.Asset{
209+
r = append(r, sbom.Asset{
209210
Path: filepath.Base(parts[0]),
210211
ReadFrom: parts[0],
211212
Label: l,
@@ -274,24 +275,24 @@ func runGithubPage(opts *githubPageCmdLineOptions) (err error) {
274275
if err != nil {
275276
return fmt.Errorf("getting assets: %w", err)
276277
}
277-
sbom := ""
278+
sbomStr := ""
278279
if opts.sbom {
279280
// Generate the assets file
280-
sbom, err = announce.GenerateReleaseSBOM(&announce.SBOMOptions{
281+
sbomStr, err = sbom.NewSBOM(&sbom.Options{
281282
ReleaseName: opts.name,
282283
Repo: opts.repo,
283284
RepoDirectory: opts.repoPath,
284285
Assets: assets,
285286
Tag: commandLineOpts.tag,
286-
Format: announce.SBOMFormat(opts.sbomFormat),
287-
})
287+
Format: sbom.SBOMFormat(opts.sbomFormat),
288+
}).Generate()
288289
if err != nil {
289290
return fmt.Errorf("generating sbom: %w", err)
290291
}
291-
opts.assets = append(opts.assets, sbom+":SPDX Software Bill of Materials (SBOM)")
292+
opts.assets = append(opts.assets, sbomStr+":SPDX Software Bill of Materials (SBOM)")
292293
// Delete the temporary sbom when we're done
293294
if commandLineOpts.nomock {
294-
defer os.Remove(sbom)
295+
defer os.Remove(sbomStr)
295296
}
296297
}
297298

@@ -301,10 +302,10 @@ func runGithubPage(opts *githubPageCmdLineOptions) (err error) {
301302
}
302303

303304
// add sbom to the path to upload
304-
newAssets[len(assets)] = sbom
305+
newAssets[len(assets)] = sbomStr
305306

306307
// Build the release page options
307-
announceOpts := announce.GitHubPageOptions{
308+
ghOpts := github.Options{
308309
AssetFiles: newAssets,
309310
Tag: commandLineOpts.tag,
310311
NoMock: commandLineOpts.nomock,
@@ -315,25 +316,25 @@ func runGithubPage(opts *githubPageCmdLineOptions) (err error) {
315316
}
316317

317318
// Assign the repository data
318-
if err := announceOpts.SetRepository(opts.repo); err != nil {
319+
if err := ghOpts.SetRepository(opts.repo); err != nil {
319320
return fmt.Errorf("assigning the repository slug: %w", err)
320321
}
321322

322323
// Assign the substitutions
323-
if err := announceOpts.ParseSubstitutions(opts.substitutions); err != nil {
324+
if err := ghOpts.ParseSubstitutions(opts.substitutions); err != nil {
324325
return fmt.Errorf("parsing template substitutions: %w", err)
325326
}
326327

327328
// Read the csutom template data
328-
if err := announceOpts.ReadTemplate(opts.template); err != nil {
329+
if err := ghOpts.ReadTemplate(opts.template); err != nil {
329330
return fmt.Errorf("reading the template file: %w", err)
330331
}
331332

332333
// Validate the options
333-
if err := announceOpts.Validate(); err != nil {
334+
if err := ghOpts.Validate(); err != nil {
334335
return fmt.Errorf("validating options: %w", err)
335336
}
336337

337338
// Run the update process
338-
return announce.UpdateGitHubPage(&announceOpts)
339+
return github.NewGitHub(&ghOpts).UpdateGitHubPage()
339340
}

pkg/anago/anagofakes/fake_release_impl.go

Lines changed: 7 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/anago/release.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/sirupsen/logrus"
2626

2727
"k8s.io/release/pkg/announce"
28+
"k8s.io/release/pkg/announce/github"
2829
"k8s.io/release/pkg/build"
2930
"k8s.io/release/pkg/gcp/gcb"
3031
"k8s.io/release/pkg/release"
@@ -147,7 +148,7 @@ type releaseImpl interface {
147148
CreateAnnouncement(
148149
options *announce.Options,
149150
) error
150-
UpdateGitHubPage(options *announce.GitHubPageOptions) error
151+
UpdateGitHubPage(options *github.Options) error
151152
PushTags(pusher *release.GitObjectPusher, tagList []string) error
152153
PushBranches(pusher *release.GitObjectPusher, branchList []string) error
153154
PushMainBranch(pusher *release.GitObjectPusher) error
@@ -260,16 +261,16 @@ func (d *DefaultRelease) InitLogFile() error {
260261

261262
func (d *defaultReleaseImpl) CreateAnnouncement(options *announce.Options) error {
262263
// Create the announcement
263-
return announce.CreateForRelease(options)
264+
return announce.NewAnnounce(options).CreateForRelease()
264265
}
265266

266267
func (d *defaultReleaseImpl) ArchiveRelease(options *release.ArchiverOptions) error {
267268
// Create a new release archiver
268269
return release.NewArchiver(options).ArchiveRelease()
269270
}
270271

271-
func (d *defaultReleaseImpl) UpdateGitHubPage(options *announce.GitHubPageOptions) error {
272-
return announce.UpdateGitHubPage(options)
272+
func (d *defaultReleaseImpl) UpdateGitHubPage(options *github.Options) error {
273+
return github.NewGitHub(options).UpdateGitHubPage()
273274
}
274275

275276
func (d *defaultReleaseImpl) PushTags(
@@ -576,7 +577,7 @@ func (d *DefaultRelease) UpdateGitHubPage() error {
576577
)
577578

578579
// Build the options set for the GitHub page
579-
ghPageOpts := &announce.GitHubPageOptions{
580+
ghPageOpts := &github.Options{
580581
Tag: d.state.versions.Prime(),
581582
NoMock: d.options.NoMock,
582583
UpdateIfReleaseExists: true,

pkg/announce/announce.go

Lines changed: 33 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,8 @@ import (
2020
"fmt"
2121
"os"
2222
"path/filepath"
23-
"regexp"
24-
"strings"
2523

2624
"github.com/sirupsen/logrus"
27-
"sigs.k8s.io/release-utils/command"
28-
"sigs.k8s.io/release-utils/util"
29-
30-
"k8s.io/release/pkg/kubecross"
3125
)
3226

3327
const (
@@ -69,16 +63,29 @@ Published by your
6963
Managers</a>.
7064
`
7165

72-
func CreateForBranch(opts *Options) error {
66+
type Announce struct {
67+
options *Options
68+
impl
69+
}
70+
71+
// NewAnnounce returns a new Announce instance.
72+
func NewAnnounce(opts *Options) *Announce {
73+
return &Announce{
74+
impl: &defaultImpl{},
75+
options: opts,
76+
}
77+
}
78+
79+
func (a *Announce) CreateForBranch() error {
7380
logrus.Infof(
7481
"Creating %s branch announcement in %s",
75-
opts.branch, opts.workDir,
82+
a.options.branch, a.options.workDir,
7683
)
7784

78-
if err := create(
79-
opts.workDir,
80-
fmt.Sprintf("Kubernetes %s branch has been created", opts.branch),
81-
fmt.Sprintf(branchAnnouncement, opts.branch),
85+
if err := a.impl.create(
86+
a.options.workDir,
87+
fmt.Sprintf("Kubernetes %s branch has been created", a.options.branch),
88+
fmt.Sprintf(branchAnnouncement, a.options.branch),
8289
); err != nil {
8390
return fmt.Errorf("creating branch announcement: %w", err)
8491
}
@@ -90,39 +97,39 @@ func CreateForBranch(opts *Options) error {
9097
return nil
9198
}
9299

93-
func CreateForRelease(opts *Options) error {
94-
logrus.Infof("Creating %s announcement in %s", opts.tag, opts.workDir)
100+
func (a *Announce) CreateForRelease() error {
101+
logrus.Infof("Creating %s announcement in %s", a.options.tag, a.options.workDir)
95102

96103
changelog := ""
97104

98105
// Read the changelog from the specified file if we got one
99-
if opts.changelogFile != "" {
100-
changelogData, err := os.ReadFile(opts.changelogFile)
106+
if a.options.changelogFile != "" {
107+
changelogData, err := os.ReadFile(a.options.changelogFile)
101108
if err != nil {
102109
return fmt.Errorf("reading changelog html file: %w", err)
103110
}
104111
changelog = string(changelogData)
105112
}
106113

107114
// ... unless it is overridden by passing the HTML directly
108-
if opts.changelogHTML != "" {
109-
changelog = opts.changelogHTML
115+
if a.options.changelogHTML != "" {
116+
changelog = a.options.changelogHTML
110117
}
111118

112-
logrus.Infof("Trying to get the Go version used to build %s...", opts.tag)
113-
goVersion, err := getGoVersion(opts.tag)
119+
logrus.Infof("Trying to get the Go version used to build %s...", a.options.tag)
120+
goVersion, err := a.impl.getGoVersion(a.options.tag)
114121
if err != nil {
115122
return err
116123
}
117124
logrus.Infof("Found the following Go version: %s", goVersion)
118125

119-
if err := create(
120-
opts.workDir,
121-
fmt.Sprintf("Kubernetes %s is live!", opts.tag),
126+
if err := a.impl.create(
127+
a.options.workDir,
128+
fmt.Sprintf("Kubernetes %s is live!", a.options.tag),
122129
fmt.Sprintf(releaseAnnouncement,
123-
opts.tag, goVersion, opts.changelogPath,
124-
filepath.Base(opts.changelogPath), opts.tag, changelog,
125-
opts.changelogPath, filepath.Base(opts.changelogPath), opts.tag,
130+
a.options.tag, goVersion, a.options.changelogPath,
131+
filepath.Base(a.options.changelogPath), a.options.tag, changelog,
132+
a.options.changelogPath, filepath.Base(a.options.changelogPath), a.options.tag,
126133
),
127134
); err != nil {
128135
return fmt.Errorf("creating release announcement: %w", err)
@@ -131,68 +138,3 @@ func CreateForRelease(opts *Options) error {
131138
logrus.Infof("Release announcement created")
132139
return nil
133140
}
134-
135-
func create(workDir, subject, message string) error {
136-
subjectFile := filepath.Join(workDir, subjectFile)
137-
//nolint:gosec // TODO(gosec): G306: Expect WriteFile permissions to be
138-
// 0600 or less
139-
if err := os.WriteFile(
140-
subjectFile, []byte(subject), 0o755,
141-
); err != nil {
142-
return fmt.Errorf(
143-
"writing subject to file %s: %w",
144-
subjectFile,
145-
err,
146-
)
147-
}
148-
logrus.Debugf("Wrote file %s", subjectFile)
149-
150-
announcementFile := filepath.Join(workDir, announcementFile)
151-
//nolint:gosec // TODO(gosec): G306: Expect WriteFile permissions to be
152-
// 0600 or less
153-
if err := os.WriteFile(
154-
announcementFile, []byte(message), 0o755,
155-
); err != nil {
156-
return fmt.Errorf(
157-
"writing announcement to file %s: %w",
158-
announcementFile,
159-
err,
160-
)
161-
}
162-
logrus.Debugf("Wrote file %s", announcementFile)
163-
164-
return nil
165-
}
166-
167-
// getGoVersion runs kube-cross container and go version inside it.
168-
// We're running kube-cross container because it's not guaranteed that
169-
// k8s-cloud-builder container will be running the same Go version as
170-
// the kube-cross container used to build the release.
171-
func getGoVersion(tag string) (string, error) {
172-
semver, err := util.TagStringToSemver(tag)
173-
if err != nil {
174-
return "", fmt.Errorf("parse version tag: %w", err)
175-
}
176-
177-
branch := fmt.Sprintf("release-%d.%d", semver.Major, semver.Minor)
178-
kc := kubecross.New()
179-
kubecrossVer, err := kc.ForBranch(branch)
180-
if err != nil {
181-
kubecrossVer, err = kc.Latest()
182-
if err != nil {
183-
return "", fmt.Errorf("get kubecross version: %w", err)
184-
}
185-
}
186-
187-
kubecrossImg := fmt.Sprintf("registry.k8s.io/build-image/kube-cross:%s", kubecrossVer)
188-
189-
res, err := command.New(
190-
"docker", "run", "--rm", kubecrossImg, "go", "version",
191-
).RunSilentSuccessOutput()
192-
if err != nil {
193-
return "", fmt.Errorf("get go version: %w", err)
194-
}
195-
196-
versionRegex := regexp.MustCompile(`^?(\d+)(\.\d+)?(\.\d+)`)
197-
return versionRegex.FindString(strings.TrimSpace(res.OutputTrimNL())), nil
198-
}

0 commit comments

Comments
 (0)