Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add relnotes in JSON to draft pull request #1821

Merged
merged 1 commit into from
Dec 12, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 85 additions & 58 deletions cmd/krel/cmd/release_notes.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ import (
)

const (
// draftFilename filename for the release notes draft
draftFilename = "release-notes-draft.md"
// draftMarkdownFile filename for the release notes draft
draftMarkdownFile = "release-notes-draft.md"
// draftJSONFile is the json version of the release notes
draftJSONFile = "release-notes-draft.json"
// serviceDirectory is where we keep the files used to generate the notes
releaseNotesWorkDir = "release-notes"
// mapsMainDirectory is where we will save the release notes maps
Expand Down Expand Up @@ -385,6 +387,9 @@ func createDraftPR(repoPath, tag string) (err error) {
if err != nil {
return errors.Wrap(err, "preparing local fork of kubernetes/sig-release")
}
defer func() {
err = sigReleaseRepo.Cleanup()
}()

// The release path inside the repository
releasePath := filepath.Join("releases", fmt.Sprintf("release-%d.%d", tagVersion.Major, tagVersion.Minor))
Expand Down Expand Up @@ -436,13 +441,22 @@ func createDraftPR(repoPath, tag string) (err error) {
return errors.Wrap(err, "building release notes results")
}

// generate the notes
logrus.Debugf("Release notes markdown will be written to %s", releaseDir)
err = ioutil.WriteFile(filepath.Join(releaseDir, draftFilename), []byte(result.markdown), 0644)
// generate the notes files
logrus.Debugf("Release notes draft files will be written to %s", releaseDir)

// Write the markdown draft
err = ioutil.WriteFile(filepath.Join(releaseDir, draftMarkdownFile), []byte(result.markdown), 0644)
if err != nil {
return errors.Wrapf(err, "writing release notes draft")
}
logrus.Infof("Release Notes Draft written to %s", filepath.Join(releaseDir, draftFilename))
logrus.Infof("Release Notes Markdown Draft written to %s", filepath.Join(releaseDir, draftMarkdownFile))

// Write the JSON file of the current notes
err = ioutil.WriteFile(filepath.Join(releaseDir, draftJSONFile), []byte(result.json), 0644)
if err != nil {
return errors.Wrapf(err, "writing release notes json file")
}
logrus.Infof("Release Notes JSON version written to %s", filepath.Join(releaseDir, draftJSONFile))

// If we are in interactive mode, ask before continuing
if !autoCreatePullRequest {
Expand All @@ -465,15 +479,71 @@ func createDraftPR(repoPath, tag string) (err error) {
return nil
}

defer func() {
err = sigReleaseRepo.Cleanup()
}()
// Create the commit
if err := createDraftCommit(
sigReleaseRepo, releasePath, "Release Notes draft for k/k "+tag,
); err != nil {
return errors.Wrap(err, "creating release notes commit")
}

// push to the user's remote
logrus.Infof("Pushing modified release notes draft to %s/%s", releaseNotesOpts.githubOrg, releaseNotesOpts.draftRepo)
if err := sigReleaseRepo.PushToRemote(userForkName, branchname); err != nil {
return errors.Wrapf(err, "pushing %s to remote", userForkName)
}

// Create a PR against k/sig-release using the github API
// TODO: Maybe read and parse the PR template from sig-release?
prBody := "**What type of PR is this?**\n"
prBody += "/kind documentation\n\n"
prBody += "**What this PR does / why we need it**:\n"
prBody += fmt.Sprintf("This PR updates the Release Notes Draft to k/k %s\n\n", tag)
prBody += "**Which issue(s) this PR fixes**:\n\n"
prBody += "**Special notes for your reviewer**:\n"
prBody += "This is an automated PR generated from `krel The Kubernetes Release Toolbox`\n\n"

// Create the pull request
logrus.Debugf(
"PR params: org: %s, repo: %s, headBranch: %s baseBranch: %s",
git.DefaultGithubOrg, git.DefaultGithubReleaseRepo, git.DefaultBranch,
fmt.Sprintf("%s:%s", releaseNotesOpts.githubOrg, branchname),
)

// Create the PR
pr, err := gh.CreatePullRequest(
git.DefaultGithubOrg, git.DefaultGithubReleaseRepo, git.DefaultBranch,
fmt.Sprintf("%s:%s", releaseNotesOpts.githubOrg, branchname),
fmt.Sprintf("Update release notes draft to version %s", tag), prBody,
)
if err != nil {
logrus.Warnf("An error has occurred while creating the pull request for %s", tag)
logrus.Warn("While the PR failed, the release notes draft was generated and submitted to your fork")
return errors.Wrap(err, "creating the pull request")
}
logrus.Infof(
"Successfully created PR: %s%s/%s/pull/%d",
github.GitHubURL, git.DefaultGithubOrg,
git.DefaultGithubReleaseRepo, pr.GetNumber(),
)
logrus.Infof("Successfully created PR #%d", pr.GetNumber())

return err
}

// createDraftCommit creates the release notes commit in the temporary clone
// of the user's sig-release fork. It will include both versions of the draft,
// the maps and cve directories and the edit session files.
func createDraftCommit(repo *git.Repo, releasePath, commitMessage string) error {
// add the updated draft
if err := sigReleaseRepo.Add(filepath.Join(releasePath, draftFilename)); err != nil {
if err := repo.Add(filepath.Join(releasePath, draftMarkdownFile)); err != nil {
return errors.Wrap(err, "adding release notes draft to staging area")
}

// add the json draft
if err := repo.Add(filepath.Join(releasePath, draftJSONFile)); err != nil {
return errors.Wrap(err, "adding release notes json to staging area")
}

// List of directories we'll consider for the PR
releaseDirectories := []struct{ Path, Name, Ext string }{
{
Expand All @@ -497,15 +567,15 @@ func createDraftPR(repoPath, tag string) (err error) {
// Add to the PR all files that exist
for _, dirData := range releaseDirectories {
// add the updated maps
if util.Exists(filepath.Join(sigReleaseRepo.Dir(), dirData.Path)) {
if util.Exists(filepath.Join(repo.Dir(), dirData.Path)) {
// Check if there are any files to commit
matches, err := filepath.Glob(filepath.Join(sigReleaseRepo.Dir(), dirData.Path, "*"+dirData.Ext))
matches, err := filepath.Glob(filepath.Join(repo.Dir(), dirData.Path, "*"+dirData.Ext))
logrus.Debugf("Adding %d %s from %s to commit", len(matches), dirData.Name, dirData.Path)
if err != nil {
return errors.Wrapf(err, "checking for %s files in %s", dirData.Ext, dirData.Path)
}
if len(matches) > 0 {
if err := sigReleaseRepo.Add(filepath.Join(dirData.Path, "*"+dirData.Ext)); err != nil {
if err := repo.Add(filepath.Join(dirData.Path, "*"+dirData.Ext)); err != nil {
return errors.Wrapf(err, "adding %s to staging area", dirData.Name)
}
}
Expand All @@ -515,52 +585,10 @@ func createDraftPR(repoPath, tag string) (err error) {
}

// add the generated draft
if err := sigReleaseRepo.UserCommit("Release Notes draft for k/k " + tag); err != nil {
if err := repo.UserCommit(commitMessage); err != nil {
return errors.Wrapf(err, "creating commit in %s/%s", releaseNotesOpts.githubOrg, releaseNotesOpts.draftRepo)
}

// push to the user's remote
logrus.Infof("Pushing modified release notes draft to %s/%s", releaseNotesOpts.githubOrg, releaseNotesOpts.draftRepo)
if err := sigReleaseRepo.PushToRemote(userForkName, branchname); err != nil {
return errors.Wrapf(err, "pushing %s to remote", userForkName)
}

// Create a PR against k/sig-release using the github API
// TODO: Maybe read and parse the PR template from sig-release?
prBody := "**What type of PR is this?**\n"
prBody += "/kind documentation\n\n"
prBody += "**What this PR does / why we need it**:\n"
prBody += fmt.Sprintf("This PR updates the Release Notes Draft to k/k %s\n\n", tag)
prBody += "**Which issue(s) this PR fixes**:\n\n"
prBody += "**Special notes for your reviewer**:\n"
prBody += "This is an automated PR generated from `krel The Kubernetes Release Toolbox`\n\n"

// Create the pull request
logrus.Debugf(
"PR params: org: %s, repo: %s, headBranch: %s baseBranch: %s",
git.DefaultGithubOrg, git.DefaultGithubReleaseRepo, git.DefaultBranch,
fmt.Sprintf("%s:%s", releaseNotesOpts.githubOrg, branchname),
)

// Create the PR
pr, err := gh.CreatePullRequest(
git.DefaultGithubOrg, git.DefaultGithubReleaseRepo, git.DefaultBranch,
fmt.Sprintf("%s:%s", releaseNotesOpts.githubOrg, branchname),
fmt.Sprintf("Update release notes draft to version %s", tag), prBody,
)
if err != nil {
logrus.Warnf("An error has occurred while creating the pull request for %s", tag)
logrus.Warn("While the PR failed, the release notes draft was generated and submitted to your fork")
return errors.Wrap(err, "creating the pull request")
}
logrus.Infof(
"Successfully created PR: %s%s/%s/pull/%d",
github.GitHubURL, git.DefaultGithubOrg,
git.DefaultGithubReleaseRepo, pr.GetNumber(),
)
logrus.Infof("Successfully created PR #%d", pr.GetNumber())

return err
return nil
}

// prepareFork Prepare a branch a repo
Expand Down Expand Up @@ -764,7 +792,6 @@ func createWebsitePR(repoPath, tag string) (err error) {
github.GitHubURL, defaultKubernetesSigsOrg,
defaultKubernetesSigsRepo, pr.GetNumber(),
)

return err
}

Expand Down