mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
releaser: Simplify the release process
Make it into a one step even for major releases.
This commit is contained in:
parent
bf537f1c6d
commit
0fa40ce58f
2 changed files with 41 additions and 103 deletions
|
@ -163,54 +163,22 @@ func fetchThemeCount() (int, error) {
|
||||||
return bytes.Count(b, []byte("\n")) - bytes.Count(b, []byte("#")), nil
|
return bytes.Count(b, []byte("\n")) - bytes.Count(b, []byte("#")), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getReleaseNotesDocsTempDirAndName(version string, final bool) (string, string) {
|
func getReleaseNotesFilename(version string) string {
|
||||||
if final {
|
return filepath.FromSlash(fmt.Sprintf("temp/%s-relnotes-ready.md", version))
|
||||||
return hugoFilepath("temp"), fmt.Sprintf("%s-relnotes-ready.md", version)
|
|
||||||
}
|
|
||||||
return hugoFilepath("temp"), fmt.Sprintf("%s-relnotes.md", version)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getReleaseNotesDocsTempFilename(version string, final bool) string {
|
|
||||||
return filepath.Join(getReleaseNotesDocsTempDirAndName(version, final))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ReleaseHandler) releaseNotesState(version string) (releaseNotesState, error) {
|
|
||||||
docsTempPath, name := getReleaseNotesDocsTempDirAndName(version, false)
|
|
||||||
_, err := os.Stat(filepath.Join(docsTempPath, name))
|
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
return releaseNotesCreated, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
docsTempPath, name = getReleaseNotesDocsTempDirAndName(version, true)
|
|
||||||
_, err = os.Stat(filepath.Join(docsTempPath, name))
|
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
return releaseNotesReady, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if !os.IsNotExist(err) {
|
|
||||||
return releaseNotesNone, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return releaseNotesNone, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ReleaseHandler) writeReleaseNotesToTemp(version string, isPatch bool, infosMain, infosDocs gitInfos) (string, error) {
|
func (r *ReleaseHandler) writeReleaseNotesToTemp(version string, isPatch bool, infosMain, infosDocs gitInfos) (string, error) {
|
||||||
docsTempPath, name := getReleaseNotesDocsTempDirAndName(version, isPatch)
|
filename := getReleaseNotesFilename(version)
|
||||||
|
|
||||||
var w io.WriteCloser
|
var w io.WriteCloser
|
||||||
|
|
||||||
if !r.try {
|
if !r.try {
|
||||||
os.Mkdir(docsTempPath, os.ModePerm)
|
f, err := os.Create(filename)
|
||||||
|
|
||||||
f, err := os.Create(filepath.Join(docsTempPath, name))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
name = f.Name()
|
|
||||||
|
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
w = f
|
w = f
|
||||||
|
@ -223,5 +191,5 @@ func (r *ReleaseHandler) writeReleaseNotesToTemp(version string, isPatch bool, i
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return name, nil
|
return filename, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,15 +32,10 @@ import (
|
||||||
|
|
||||||
const commitPrefix = "releaser:"
|
const commitPrefix = "releaser:"
|
||||||
|
|
||||||
type releaseNotesState int
|
|
||||||
|
|
||||||
const (
|
|
||||||
releaseNotesNone = iota
|
|
||||||
releaseNotesCreated
|
|
||||||
releaseNotesReady
|
|
||||||
)
|
|
||||||
|
|
||||||
// ReleaseHandler provides functionality to release a new version of Hugo.
|
// ReleaseHandler provides functionality to release a new version of Hugo.
|
||||||
|
// Test this locally without doing an actual release:
|
||||||
|
// go run -tags release main.go release --skip-publish --try -r 0.90.0
|
||||||
|
// Or a variation of the above -- the skip-publish flag makes sure that any changes are performed to the local Git only.
|
||||||
type ReleaseHandler struct {
|
type ReleaseHandler struct {
|
||||||
cliVersion string
|
cliVersion string
|
||||||
|
|
||||||
|
@ -91,6 +86,8 @@ func (r *ReleaseHandler) Run() error {
|
||||||
return errors.New("GITHUB_TOKEN not set, create one here with the repo scope selected: https://github.com/settings/tokens/new")
|
return errors.New("GITHUB_TOKEN not set, create one here with the repo scope selected: https://github.com/settings/tokens/new")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Start release from %q\n", wd())
|
||||||
|
|
||||||
newVersion, finalVersion := r.calculateVersions()
|
newVersion, finalVersion := r.calculateVersions()
|
||||||
|
|
||||||
version := newVersion.String()
|
version := newVersion.String()
|
||||||
|
@ -124,61 +121,35 @@ func (r *ReleaseHandler) Run() error {
|
||||||
var (
|
var (
|
||||||
gitCommits gitInfos
|
gitCommits gitInfos
|
||||||
gitCommitsDocs gitInfos
|
gitCommitsDocs gitInfos
|
||||||
relNotesState releaseNotesState
|
|
||||||
)
|
)
|
||||||
|
|
||||||
relNotesState, err = r.releaseNotesState(version)
|
defer r.gitPush() // TODO(bep)
|
||||||
|
|
||||||
|
gitCommits, err = getGitInfos(changeLogFromTag, "hugo", "", !r.try)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareReleaseNotes := isPatch || relNotesState == releaseNotesNone
|
// TODO(bep) explicit tag?
|
||||||
shouldRelease := isPatch || relNotesState == releaseNotesReady
|
gitCommitsDocs, err = getGitInfos("", "hugoDocs", "../hugoDocs", !r.try)
|
||||||
|
if err != nil {
|
||||||
defer r.gitPush() // TODO(bep)
|
return err
|
||||||
|
|
||||||
if prepareReleaseNotes || shouldRelease {
|
|
||||||
gitCommits, err = getGitInfos(changeLogFromTag, "hugo", "", !r.try)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(bep) explicit tag?
|
|
||||||
gitCommitsDocs, err = getGitInfos("", "hugoDocs", "../hugoDocs", !r.try)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if relNotesState == releaseNotesCreated {
|
releaseNotesFile, err := r.writeReleaseNotesToTemp(version, isPatch, gitCommits, gitCommitsDocs)
|
||||||
fmt.Println("Release notes created, but not ready. Rename to *-ready.md to continue ...")
|
if err != nil {
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if prepareReleaseNotes {
|
if _, err := r.git("add", releaseNotesFile); err != nil {
|
||||||
releaseNotesFile, err := r.writeReleaseNotesToTemp(version, isPatch, gitCommits, gitCommitsDocs)
|
return err
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := r.git("add", releaseNotesFile); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
commitMsg := fmt.Sprintf("%s Add release notes for %s", commitPrefix, newVersion)
|
|
||||||
if !isPatch {
|
|
||||||
commitMsg += "\n\nRename to *-ready.md to continue."
|
|
||||||
}
|
|
||||||
commitMsg += "\n[ci skip]"
|
|
||||||
|
|
||||||
if _, err := r.git("commit", "-m", commitMsg); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !shouldRelease {
|
commitMsg := fmt.Sprintf("%s Add release notes for %s", commitPrefix, newVersion)
|
||||||
fmt.Printf("Skip release ... ")
|
commitMsg += "\n[ci skip]"
|
||||||
return nil
|
|
||||||
|
if _, err := r.git("commit", "-m", commitMsg); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := r.bumpVersions(newVersion); err != nil {
|
if err := r.bumpVersions(newVersion); err != nil {
|
||||||
|
@ -189,7 +160,7 @@ func (r *ReleaseHandler) Run() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := r.git("tag", "-a", tag, "-m", fmt.Sprintf("%s %s [ci skip]", commitPrefix, newVersion)); err != nil {
|
if _, err := r.git("tag", "-a", tag, "-m", fmt.Sprintf("%s %s\n\n[ci skip]", commitPrefix, newVersion)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,8 +170,6 @@ func (r *ReleaseHandler) Run() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseNotesFile := getReleaseNotesDocsTempFilename(version, true)
|
|
||||||
|
|
||||||
if err := r.release(releaseNotesFile); err != nil {
|
if err := r.release(releaseNotesFile); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -295,8 +264,8 @@ func (r *ReleaseHandler) bumpVersions(ver hugo.Version) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ReleaseHandler) replaceInFile(filename string, oldNew ...string) error {
|
func (r *ReleaseHandler) replaceInFile(filename string, oldNew ...string) error {
|
||||||
fullFilename := hugoFilepath(filename)
|
filename = filepath.FromSlash(filename)
|
||||||
fi, err := os.Stat(fullFilename)
|
fi, err := os.Stat(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -306,7 +275,7 @@ func (r *ReleaseHandler) replaceInFile(filename string, oldNew ...string) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := ioutil.ReadFile(fullFilename)
|
b, err := ioutil.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -317,17 +286,18 @@ func (r *ReleaseHandler) replaceInFile(filename string, oldNew ...string) error
|
||||||
newContent = re.ReplaceAllString(newContent, oldNew[i+1])
|
newContent = re.ReplaceAllString(newContent, oldNew[i+1])
|
||||||
}
|
}
|
||||||
|
|
||||||
return ioutil.WriteFile(fullFilename, []byte(newContent), fi.Mode())
|
return ioutil.WriteFile(filename, []byte(newContent), fi.Mode())
|
||||||
}
|
|
||||||
|
|
||||||
func hugoFilepath(filename string) string {
|
|
||||||
pwd, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
return filepath.Join(pwd, filename)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isCI() bool {
|
func isCI() bool {
|
||||||
return os.Getenv("CI") != ""
|
return os.Getenv("CI") != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func wd() string {
|
||||||
|
p, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue