mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
releaser: Rework and simplify to use GitHub only for release notes
This commit is contained in:
parent
bf1564bd2c
commit
24a893cf83
4 changed files with 27 additions and 177 deletions
|
@ -34,12 +34,10 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type changeLog struct {
|
type changeLog struct {
|
||||||
Version string
|
Version string
|
||||||
Enhancements map[string]gitInfos
|
Notes gitInfos
|
||||||
Fixes map[string]gitInfos
|
All gitInfos
|
||||||
Notes gitInfos
|
Docs gitInfos
|
||||||
All gitInfos
|
|
||||||
Docs gitInfos
|
|
||||||
|
|
||||||
// Overall stats
|
// Overall stats
|
||||||
Repo *gitHubRepo
|
Repo *gitHubRepo
|
||||||
|
@ -48,66 +46,19 @@ type changeLog struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newChangeLog(infos, docInfos gitInfos) *changeLog {
|
func newChangeLog(infos, docInfos gitInfos) *changeLog {
|
||||||
return &changeLog{
|
log := &changeLog{
|
||||||
Enhancements: make(map[string]gitInfos),
|
Docs: docInfos,
|
||||||
Fixes: make(map[string]gitInfos),
|
|
||||||
All: infos,
|
|
||||||
Docs: docInfos,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *changeLog) addGitInfo(isFix bool, info gitInfo, category string) {
|
|
||||||
var (
|
|
||||||
infos gitInfos
|
|
||||||
found bool
|
|
||||||
segment map[string]gitInfos
|
|
||||||
)
|
|
||||||
|
|
||||||
if category == notesChanges {
|
|
||||||
l.Notes = append(l.Notes, info)
|
|
||||||
return
|
|
||||||
} else if isFix {
|
|
||||||
segment = l.Fixes
|
|
||||||
} else {
|
|
||||||
segment = l.Enhancements
|
|
||||||
}
|
}
|
||||||
|
|
||||||
infos, found = segment[category]
|
|
||||||
if !found {
|
|
||||||
infos = gitInfos{}
|
|
||||||
}
|
|
||||||
|
|
||||||
infos = append(infos, info)
|
|
||||||
segment[category] = infos
|
|
||||||
}
|
|
||||||
|
|
||||||
func gitInfosToChangeLog(infos, docInfos gitInfos) *changeLog {
|
|
||||||
log := newChangeLog(infos, docInfos)
|
|
||||||
for _, info := range infos {
|
for _, info := range infos {
|
||||||
los := strings.ToLower(info.Subject)
|
|
||||||
isFix := strings.Contains(los, "fix")
|
|
||||||
category := otherChanges
|
|
||||||
|
|
||||||
// TODO(bep) improve
|
// TODO(bep) improve
|
||||||
if regexp.MustCompile("(?i)deprecate").MatchString(los) {
|
if regexp.MustCompile("(?i)deprecate").MatchString(info.Subject) {
|
||||||
category = notesChanges
|
log.Notes = append(log.Notes, info)
|
||||||
} else if regexp.MustCompile("(?i)tpl|tplimpl:|layout").MatchString(los) {
|
|
||||||
category = templateChanges
|
|
||||||
} else if regexp.MustCompile("(?i)hugolib:").MatchString(los) {
|
|
||||||
category = coreChanges
|
|
||||||
} else if regexp.MustCompile("(?i)out(put)?:|media:|Output|Media").MatchString(los) {
|
|
||||||
category = outChanges
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trim package prefix.
|
|
||||||
colonIdx := strings.Index(info.Subject, ":")
|
|
||||||
if colonIdx != -1 && colonIdx < (len(info.Subject)/2) {
|
|
||||||
info.Subject = info.Subject[colonIdx+1:]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.All = append(log.All, info)
|
||||||
info.Subject = strings.TrimSpace(info.Subject)
|
info.Subject = strings.TrimSpace(info.Subject)
|
||||||
|
|
||||||
log.addGitInfo(isFix, info, category)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return log
|
return log
|
||||||
|
@ -255,7 +206,7 @@ func getGitInfosBefore(ref, tag, repo, repoPath string, remote bool) (gitInfos,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore autogenerated commits etc. in change log. This is a regexp.
|
// Ignore autogenerated commits etc. in change log. This is a regexp.
|
||||||
const ignoredCommits = "releaser?:|snapcraft:|Merge commit|Squashed"
|
const ignoredCommits = "snapcraft:|Merge commit|Squashed"
|
||||||
|
|
||||||
func gitLogBefore(ref, tag, repoPath string) (string, error) {
|
func gitLogBefore(ref, tag, repoPath string) (string, error) {
|
||||||
var prevTag string
|
var prevTag string
|
||||||
|
|
|
@ -25,11 +25,10 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
issueLinkTemplate = "[#%d](https://github.com/gohugoio/hugo/issues/%d)"
|
issueLinkTemplate = "#%d"
|
||||||
linkTemplate = "[%s](%s)"
|
linkTemplate = "[%s](%s)"
|
||||||
releaseNotesMarkdownTemplatePatchRelease = `
|
releaseNotesMarkdownTemplatePatchRelease = `
|
||||||
{{ if eq (len .All) 1 }}
|
{{ if eq (len .All) 1 }}
|
||||||
|
@ -39,9 +38,9 @@ This is a bug-fix release with a couple of important fixes.
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ range .All }}
|
{{ range .All }}
|
||||||
{{- if .GitHubCommit -}}
|
{{- if .GitHubCommit -}}
|
||||||
* {{ .Subject }} {{ . | commitURL }} {{ . | authorURL }} {{ range .Issues }}{{ . | issue }}{{ end }}
|
* {{ .Subject }} {{ .Hash }} {{ . | authorURL }} {{ range .Issues }}{{ . | issue }} {{ end }}
|
||||||
{{ else -}}
|
{{ else -}}
|
||||||
* {{ .Subject }} {{ range .Issues }}{{ . | issue }}{{ end }}
|
* {{ .Subject }} {{ range .Issues }}{{ . | issue }} {{ end }}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
|
@ -83,41 +82,17 @@ Hugo now has:
|
||||||
## Notes
|
## Notes
|
||||||
{{ template "change-section" . }}
|
{{ template "change-section" . }}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
## Enhancements
|
{{ with .All }}
|
||||||
{{ template "change-headers" .Enhancements -}}
|
## Changes
|
||||||
## Fixes
|
|
||||||
{{ template "change-headers" .Fixes -}}
|
|
||||||
|
|
||||||
{{ define "change-headers" }}
|
|
||||||
{{ $tmplChanges := index . "templateChanges" -}}
|
|
||||||
{{- $outChanges := index . "outChanges" -}}
|
|
||||||
{{- $coreChanges := index . "coreChanges" -}}
|
|
||||||
{{- $otherChanges := index . "otherChanges" -}}
|
|
||||||
{{- with $tmplChanges -}}
|
|
||||||
### Templates
|
|
||||||
{{ template "change-section" . }}
|
{{ template "change-section" . }}
|
||||||
{{- end -}}
|
|
||||||
{{- with $outChanges -}}
|
|
||||||
### Output
|
|
||||||
{{ template "change-section" . }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- with $coreChanges -}}
|
|
||||||
### Core
|
|
||||||
{{ template "change-section" . }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- with $otherChanges -}}
|
|
||||||
### Other
|
|
||||||
{{ template "change-section" . }}
|
|
||||||
{{- end -}}
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
|
||||||
{{ define "change-section" }}
|
{{ define "change-section" }}
|
||||||
{{ range . }}
|
{{ range . }}
|
||||||
{{- if .GitHubCommit -}}
|
{{- if .GitHubCommit -}}
|
||||||
* {{ .Subject }} {{ . | commitURL }} {{ . | authorURL }} {{ range .Issues }}{{ . | issue }}{{ end }}
|
* {{ .Subject }} {{ .Hash }} {{ . | authorURL }} {{ range .Issues }}{{ . | issue }} {{ end }}
|
||||||
{{ else -}}
|
{{ else -}}
|
||||||
* {{ .Subject }} {{ range .Issues }}{{ . | issue }}{{ end }}
|
* {{ .Subject }} {{ range .Issues }}{{ . | issue }} {{ end }}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
@ -129,7 +104,7 @@ var templateFuncs = template.FuncMap{
|
||||||
return !strings.HasSuffix(c.Version, "0")
|
return !strings.HasSuffix(c.Version, "0")
|
||||||
},
|
},
|
||||||
"issue": func(id int) string {
|
"issue": func(id int) string {
|
||||||
return fmt.Sprintf(issueLinkTemplate, id, id)
|
return fmt.Sprintf(issueLinkTemplate, id)
|
||||||
},
|
},
|
||||||
"commitURL": func(info gitInfo) string {
|
"commitURL": func(info gitInfo) string {
|
||||||
if info.GitHubCommit.HTMLURL == "" {
|
if info.GitHubCommit.HTMLURL == "" {
|
||||||
|
@ -147,7 +122,7 @@ var templateFuncs = template.FuncMap{
|
||||||
|
|
||||||
func writeReleaseNotes(version string, infosMain, infosDocs gitInfos, to io.Writer) error {
|
func writeReleaseNotes(version string, infosMain, infosDocs gitInfos, to io.Writer) error {
|
||||||
client := newGitHubAPI("hugo")
|
client := newGitHubAPI("hugo")
|
||||||
changes := gitInfosToChangeLog(infosMain, infosDocs)
|
changes := newChangeLog(infosMain, infosDocs)
|
||||||
changes.Version = version
|
changes.Version = version
|
||||||
repo, err := client.fetchRepo()
|
repo, err := client.fetchRepo()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -265,57 +240,3 @@ func (r *ReleaseHandler) writeReleaseNotesToTemp(version string, isPatch bool, i
|
||||||
|
|
||||||
return name, nil
|
return name, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ReleaseHandler) writeReleaseNotesToDocs(title, description, sourceFilename string) (string, error) {
|
|
||||||
targetFilename := "index.md"
|
|
||||||
bundleDir := strings.TrimSuffix(filepath.Base(sourceFilename), "-ready.md")
|
|
||||||
contentDir := hugoFilepath("docs/content/en/news/" + bundleDir)
|
|
||||||
targetFullFilename := filepath.Join(contentDir, targetFilename)
|
|
||||||
|
|
||||||
if r.try {
|
|
||||||
fmt.Printf("Write release notes to /docs: Bundle %q Dir: %q\n", bundleDir, contentDir)
|
|
||||||
return targetFullFilename, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.MkdirAll(contentDir, os.ModePerm); err != nil {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := ioutil.ReadFile(sourceFilename)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err := os.Create(targetFullFilename)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
fmTail := ""
|
|
||||||
if !strings.HasSuffix(title, ".0") {
|
|
||||||
// Bug fix release
|
|
||||||
fmTail = `
|
|
||||||
images:
|
|
||||||
- images/blog/hugo-bug-poster.png
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := f.WriteString(fmt.Sprintf(`
|
|
||||||
---
|
|
||||||
date: %s
|
|
||||||
title: %q
|
|
||||||
description: %q
|
|
||||||
categories: ["Releases"]%s
|
|
||||||
---
|
|
||||||
|
|
||||||
`, time.Now().Format("2006-01-02"), title, description, fmTail)); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := f.Write(b); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return targetFullFilename, nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -26,19 +26,21 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func _TestReleaseNotesWriter(t *testing.T) {
|
func _TestReleaseNotesWriter(t *testing.T) {
|
||||||
|
skipIfNoToken(t)
|
||||||
if os.Getenv("CI") != "" {
|
if os.Getenv("CI") != "" {
|
||||||
// Travis has an ancient git with no --invert-grep: https://github.com/travis-ci/travis-ci/issues/6328
|
// Travis has an ancient git with no --invert-grep: https://github.com/travis-ci/travis-ci/issues/6328
|
||||||
t.Skip("Skip git test on CI to make Travis happy.")
|
t.Skip("Skip git test on CI to make Travis happy..")
|
||||||
}
|
}
|
||||||
|
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
|
|
||||||
// TODO(bep) consider to query GitHub directly for the gitlog with author info, probably faster.
|
// TODO(bep) consider to query GitHub directly for the gitlog with author info, probably faster.
|
||||||
infos, err := getGitInfosBefore("HEAD", "v0.20", "hugo", "", false)
|
infos, err := getGitInfosBefore("HEAD", "v0.89.0", "hugo", "", false)
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
|
|
||||||
c.Assert(writeReleaseNotes("0.21", infos, infos, &b), qt.IsNil)
|
c.Assert(writeReleaseNotes("0.89.0", infos, infos, &b), qt.IsNil)
|
||||||
|
|
||||||
fmt.Println(b.String())
|
fmt.Println(b.String())
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,11 +181,6 @@ func (r *ReleaseHandler) Run() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// For docs, for now we assume that:
|
|
||||||
// The /docs subtree is up to date and ready to go.
|
|
||||||
// The hugoDocs/dev and hugoDocs/master must be merged manually after release.
|
|
||||||
// TODO(bep) improve this when we see how it works.
|
|
||||||
|
|
||||||
if err := r.bumpVersions(newVersion); err != nil {
|
if err := r.bumpVersions(newVersion); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -194,27 +189,6 @@ func (r *ReleaseHandler) Run() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseNotesFile := getReleaseNotesDocsTempFilename(version, true)
|
|
||||||
|
|
||||||
title, description := version, version
|
|
||||||
if isPatch {
|
|
||||||
title = "Hugo " + version + ": A couple of Bug Fixes"
|
|
||||||
description = "This version fixes a couple of bugs introduced in " + mainVersion.String() + "."
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the release notes to the docs site as well.
|
|
||||||
docFile, err := r.writeReleaseNotesToDocs(title, description, releaseNotesFile)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := r.git("add", docFile); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := r.git("commit", "-m", fmt.Sprintf("%s Add release notes to /docs for release of %s\n\n[ci skip]", commitPrefix, newVersion)); err != nil {
|
|
||||||
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 [ci skip]", commitPrefix, newVersion)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -225,6 +199,8 @@ 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
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue