diff --git a/commands/release.go b/commands/release.go index c9275a0f..74dc7012 100644 --- a/commands/release.go +++ b/commands/release.go @@ -31,6 +31,7 @@ type releaseCommandeer struct { patchLevel int skipPublish bool + try bool step int } @@ -53,10 +54,11 @@ func createReleaser() *releaseCommandeer { r.cmd.PersistentFlags().IntVarP(&r.patchLevel, "patch", "p", 0, "patch level, defaults to 0 for main releases") r.cmd.PersistentFlags().IntVarP(&r.step, "step", "s", -1, "release step, defaults to -1 for all steps.") r.cmd.PersistentFlags().BoolVarP(&r.skipPublish, "skip-publish", "", false, "skip all publishing pipes of the release") + r.cmd.PersistentFlags().BoolVarP(&r.try, "try", "", false, "simulate a release, i.e. no changes") return r } func (r *releaseCommandeer) release() error { - return releaser.New(r.patchLevel, r.step, r.skipPublish).Run() + return releaser.New(r.patchLevel, r.step, r.skipPublish, r.try).Run() } diff --git a/releaser/releasenotes_writer.go b/releaser/releasenotes_writer.go index 9dbdf61a..ced9254a 100644 --- a/releaser/releasenotes_writer.go +++ b/releaser/releasenotes_writer.go @@ -193,29 +193,49 @@ func getReleaseNotesDocsTempFilename(version string) string { return filepath.Join(getReleaseNotesDocsTempDirAndName(version)) } -func writeReleaseNotesToTemp(version string, infos gitInfos) (string, error) { +func (r *ReleaseHandler) writeReleaseNotesToTemp(version string, infos gitInfos) (string, error) { + docsTempPath, name := getReleaseNotesDocsTempDirAndName(version) - os.Mkdir(docsTempPath, os.ModePerm) - f, err := os.Create(filepath.Join(docsTempPath, name)) - if err != nil { + var ( + w io.WriteCloser + ) + + if !r.try { + os.Mkdir(docsTempPath, os.ModePerm) + + f, err := os.Create(filepath.Join(docsTempPath, name)) + if err != nil { + return "", err + } + + name = f.Name() + + defer f.Close() + + w = f + + } else { + w = os.Stdout + } + + if err := writeReleaseNotes(version, infos, w); err != nil { return "", err } - defer f.Close() - - if err := writeReleaseNotes(version, infos, f); err != nil { - return "", err - } - - return f.Name(), nil + return name, nil } -func writeReleaseNotesToDocs(title, sourceFilename string) (string, error) { +func (r *ReleaseHandler) writeReleaseNotesToDocs(title, sourceFilename string) (string, error) { targetFilename := filepath.Base(sourceFilename) contentDir := hugoFilepath("docs/content/release-notes") targetFullFilename := filepath.Join(contentDir, targetFilename) + + if r.try { + return targetFullFilename, nil + } + os.Mkdir(contentDir, os.ModePerm) b, err := ioutil.ReadFile(sourceFilename) diff --git a/releaser/releaser.go b/releaser/releaser.go index f3b4358a..52a74dc7 100644 --- a/releaser/releaser.go +++ b/releaser/releaser.go @@ -39,6 +39,11 @@ type ReleaseHandler struct { // 3: Release step int skipPublish bool + + // Just simulate, no actual changes. + try bool + + git func(args ...string) (string, error) } func (r ReleaseHandler) shouldRelease() bool { @@ -82,8 +87,19 @@ func (r ReleaseHandler) calculateVersions(current helpers.HugoVersion) (helpers. return newVersion, finalVersion } -func New(patch, step int, skipPublish bool) *ReleaseHandler { - return &ReleaseHandler{patch: patch, step: step, skipPublish: skipPublish} +func New(patch, step int, skipPublish, try bool) *ReleaseHandler { + rh := &ReleaseHandler{patch: patch, step: step, skipPublish: skipPublish, try: try} + + if try { + rh.git = func(args ...string) (string, error) { + fmt.Println("git", args) + return "", nil + } + } else { + rh.git = git + } + + return rh } func (r *ReleaseHandler) Run() error { @@ -121,22 +137,22 @@ func (r *ReleaseHandler) Run() error { var gitCommits gitInfos if r.shouldPrepareReleasenotes() || r.shouldRelease() { - gitCommits, err = getGitInfos(changeLogFromTag, true) + gitCommits, err = getGitInfos(changeLogFromTag, !r.try) if err != nil { return err } } if r.shouldPrepareReleasenotes() { - releaseNotesFile, err := writeReleaseNotesToTemp(version, gitCommits) + releaseNotesFile, err := r.writeReleaseNotesToTemp(version, gitCommits) if err != nil { return err } - if _, err := git("add", releaseNotesFile); err != nil { + if _, err := r.git("add", releaseNotesFile); err != nil { return err } - if _, err := git("commit", "-m", fmt.Sprintf("%s Add release notes draft for %s\n\n[ci skip]", commitPrefix, newVersion)); err != nil { + if _, err := r.git("commit", "-m", fmt.Sprintf("%s Add release notes draft for %s\n\n[ci skip]", commitPrefix, newVersion)); err != nil { return err } } @@ -146,26 +162,26 @@ func (r *ReleaseHandler) Run() error { // Make sure the docs submodule is up to date. // TODO(bep) improve this. Maybe it was not such a good idea to do // this in the sobmodule directly. - if _, err := git("submodule", "update", "--init"); err != nil { + if _, err := r.git("submodule", "update", "--init"); err != nil { return err } //git submodule update - if _, err := git("submodule", "update", "--remote", "--merge"); err != nil { + if _, err := r.git("submodule", "update", "--remote", "--merge"); err != nil { return err } // TODO(bep) the above may not have changed anything. - if _, err := git("commit", "-a", "-m", fmt.Sprintf("%s Update /docs [ci skip]", commitPrefix)); err != nil { + if _, err := r.git("commit", "-a", "-m", fmt.Sprintf("%s Update /docs [ci skip]", commitPrefix)); err != nil { return err } } - if err := bumpVersions(newVersion); err != nil { + if err := r.bumpVersions(newVersion); err != nil { return err } for _, repo := range []string{"docs", "."} { - if _, err := git("-C", repo, "commit", "-a", "-m", fmt.Sprintf("%s Bump versions for release of %s\n\n[ci skip]", commitPrefix, newVersion)); err != nil { + if _, err := r.git("-C", repo, "commit", "-a", "-m", fmt.Sprintf("%s Bump versions for release of %s\n\n[ci skip]", commitPrefix, newVersion)); err != nil { return err } } @@ -179,28 +195,28 @@ func (r *ReleaseHandler) Run() error { releaseNotesFile := getReleaseNotesDocsTempFilename(version) // Write the release notes to the docs site as well. - docFile, err := writeReleaseNotesToDocs(version, releaseNotesFile) + docFile, err := r.writeReleaseNotesToDocs(version, releaseNotesFile) if err != nil { return err } - if _, err := git("-C", "docs", "add", docFile); err != nil { + if _, err := r.git("-C", "docs", "add", docFile); err != nil { return err } - if _, err := git("-C", "docs", "commit", "-m", fmt.Sprintf("%s Add release notes to /docs for release of %s\n\n[ci skip]", commitPrefix, newVersion)); err != nil { + if _, err := r.git("-C", "docs", "commit", "-m", fmt.Sprintf("%s Add release notes to /docs for release of %s\n\n[ci skip]", commitPrefix, newVersion)); err != nil { return err } for i, repo := range []string{"docs", "."} { if i == 1 { - if _, err := git("add", "docs"); err != nil { + if _, err := r.git("add", "docs"); err != nil { return err } - if _, err := git("commit", "-m", fmt.Sprintf("%s Update /docs to %s [ci skip]", commitPrefix, newVersion)); err != nil { + if _, err := r.git("commit", "-m", fmt.Sprintf("%s Update /docs to %s [ci skip]", commitPrefix, newVersion)); err != nil { return err } } - if _, err := git("-C", repo, "tag", "-a", tag, "-m", fmt.Sprintf("%s %s [ci deploy]", commitPrefix, newVersion)); err != nil { + if _, err := r.git("-C", repo, "tag", "-a", tag, "-m", fmt.Sprintf("%s %s [ci deploy]", commitPrefix, newVersion)); err != nil { return err } @@ -208,7 +224,7 @@ func (r *ReleaseHandler) Run() error { if i == 0 { repoURL = "git@github.com:gohugoio/hugoDocs.git" } - if _, err := git("-C", repo, "push", repoURL, "origin/master", tag); err != nil { + if _, err := r.git("-C", repo, "push", repoURL, "origin/master", tag); err != nil { return err } } @@ -222,17 +238,19 @@ func (r *ReleaseHandler) Run() error { return err } - if err := bumpVersions(finalVersion); err != nil { + if err := r.bumpVersions(finalVersion); err != nil { return err } - // No longer needed. - if err := os.Remove(releaseNotesFile); err != nil { - return err + if !r.try { + // No longer needed. + if err := os.Remove(releaseNotesFile); err != nil { + return err + } } for _, repo := range []string{"docs", "."} { - if _, err := git("-C", repo, "commit", "-a", "-m", fmt.Sprintf("%s Prepare repository for %s\n\n[ci skip]", commitPrefix, finalVersion)); err != nil { + if _, err := r.git("-C", repo, "commit", "-a", "-m", fmt.Sprintf("%s Prepare repository for %s\n\n[ci skip]", commitPrefix, finalVersion)); err != nil { return err } } @@ -241,6 +259,11 @@ func (r *ReleaseHandler) Run() error { } func (r *ReleaseHandler) release(releaseNotesFile string) error { + if r.try { + fmt.Println("Skip goreleaser...") + return nil + } + cmd := exec.Command("goreleaser", "--release-notes", releaseNotesFile, "--skip-publish="+fmt.Sprint(r.skipPublish)) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr @@ -251,7 +274,7 @@ func (r *ReleaseHandler) release(releaseNotesFile string) error { return nil } -func bumpVersions(ver helpers.HugoVersion) error { +func (r *ReleaseHandler) bumpVersions(ver helpers.HugoVersion) error { fromDev := "" toDev := "" @@ -261,7 +284,7 @@ func bumpVersions(ver helpers.HugoVersion) error { fromDev = "-DEV" } - if err := replaceInFile("helpers/hugo.go", + if err := r.replaceInFile("helpers/hugo.go", `Number:(\s{4,})(.*),`, fmt.Sprintf(`Number:${1}%.2f,`, ver.Number), `PatchLevel:(\s*)(.*),`, fmt.Sprintf(`PatchLevel:${1}%d,`, ver.PatchLevel), fmt.Sprintf(`Suffix:(\s{4,})"%s",`, fromDev), fmt.Sprintf(`Suffix:${1}"%s",`, toDev)); err != nil { @@ -272,7 +295,7 @@ func bumpVersions(ver helpers.HugoVersion) error { if ver.Suffix != "" { snapcraftGrade = "devel" } - if err := replaceInFile("snapcraft.yaml", + if err := r.replaceInFile("snapcraft.yaml", `version: "(.*)"`, fmt.Sprintf(`version: "%s"`, ver), `grade: (.*) #`, fmt.Sprintf(`grade: %s #`, snapcraftGrade)); err != nil { return err @@ -287,13 +310,13 @@ func bumpVersions(ver helpers.HugoVersion) error { minVersion = ver.String() } - if err := replaceInFile("commands/new.go", + if err := r.replaceInFile("commands/new.go", `min_version = "(.*)"`, fmt.Sprintf(`min_version = "%s"`, minVersion)); err != nil { return err } // docs/config.toml - if err := replaceInFile("docs/config.toml", + if err := r.replaceInFile("docs/config.toml", `release = "(.*)"`, fmt.Sprintf(`release = "%s"`, ver)); err != nil { return err } @@ -301,13 +324,18 @@ func bumpVersions(ver helpers.HugoVersion) error { return nil } -func replaceInFile(filename string, oldNew ...string) error { +func (r *ReleaseHandler) replaceInFile(filename string, oldNew ...string) error { fullFilename := hugoFilepath(filename) fi, err := os.Stat(fullFilename) if err != nil { return err } + if r.try { + fmt.Printf("Replace in %q: %q\n", filename, oldNew) + return nil + } + b, err := ioutil.ReadFile(fullFilename) if err != nil { return err diff --git a/releaser/releaser_test.go b/releaser/releaser_test.go index c20e17bf..2e5a545a 100644 --- a/releaser/releaser_test.go +++ b/releaser/releaser_test.go @@ -34,37 +34,37 @@ func _TestCalculateVersions(t *testing.T) { v2 string }{ { - New(0, 0, true), + New(0, 0, true, true), startVersion, "0.20", "0.21-DEV", }, { - New(2, 0, true), + New(2, 0, true, true), startVersion, "0.20.2", "0.20-DEV", }, { - New(0, 1, true), + New(0, 1, true, true), startVersion, "0.20", "0.21-DEV", }, { - New(0, 3, true), + New(0, 3, true, true), startVersion, "0.20", "0.21-DEV", }, { - New(3, 1, true), + New(3, 1, true, true), startVersion, "0.20.3", "0.20-DEV", }, { - New(3, 3, true), + New(3, 3, true, true), startVersion.Next(), "0.21", "0.21-DEV",