You've already forked go-semantic-release
feat(template): allow custom changelog template
This commit is contained in:
11
README.md
11
README.md
@@ -110,9 +110,20 @@ assets:
|
|||||||
|
|
||||||
#### Changelog
|
#### Changelog
|
||||||
|
|
||||||
|
Following variables can be used for templates:
|
||||||
|
* `Commits` string
|
||||||
|
* `Version` string
|
||||||
|
* `Now` time.Time
|
||||||
|
* `Backtick` string
|
||||||
|
* `HasDocker` bool
|
||||||
|
* `HasDockerLatest` bool
|
||||||
|
* `DockerRepository` string
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
changelog:
|
changelog:
|
||||||
printAll: false ## Print all valid commits to changelog
|
printAll: false ## Print all valid commits to changelog
|
||||||
|
title: "v{{.Version}} ({{.Now.Format "2006-01-02"}})" ## Used for releases (go template)
|
||||||
|
templatePath: "./examples/changelog.tmpl" ## Path to a template file (go template)
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Docker
|
##### Docker
|
||||||
|
|||||||
16
examples/changelog.tmpl
Normal file
16
examples/changelog.tmpl
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# My custom release template v{{$.Version}} ({{.Now.Format "2006-01-02"}})
|
||||||
|
{{ .Commits -}}
|
||||||
|
{{ if .HasDocker}}
|
||||||
|
## Docker image
|
||||||
|
|
||||||
|
New docker image is released under {{$.Backtick}}{{.DockerRepository}}:{{.Version}}{{$.Backtick}}
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
{{$.Backtick}}docker run {{.DockerRepository}}:{{.Version}}{{$.Backtick}}
|
||||||
|
{{ if .HasDockerLatest}}
|
||||||
|
or
|
||||||
|
|
||||||
|
{{$.Backtick}}docker run {{.DockerRepository}}:latest{{$.Backtick}}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
@@ -2,6 +2,7 @@ package changelog
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
@@ -13,9 +14,7 @@ import (
|
|||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultChangelogTitle string = `v{{.Version}} ({{.Now.Format "2006-01-02"}})`
|
const defaultCommitList string = `{{ range $index,$commit := .BreakingChanges -}}
|
||||||
const defaultChangelog string = `# v{{$.Version}} ({{.Now.Format "2006-01-02"}})
|
|
||||||
{{ range $index,$commit := .BreakingChanges -}}
|
|
||||||
{{ if eq $index 0 }}
|
{{ if eq $index 0 }}
|
||||||
## BREAKING CHANGES
|
## BREAKING CHANGES
|
||||||
{{ end}}
|
{{ end}}
|
||||||
@@ -30,7 +29,10 @@ introduced by commit:
|
|||||||
* **{{$.Backtick}}{{$commit.Scope}}{{$.Backtick}}** {{$commit.ParsedMessage}} {{if $.HasURL}} ([{{ printf "%.7s" $commit.Commit.Hash}}]({{ replace $.URL "{{hash}}" $commit.Commit.Hash}})) {{end}}
|
* **{{$.Backtick}}{{$commit.Scope}}{{$.Backtick}}** {{$commit.ParsedMessage}} {{if $.HasURL}} ([{{ printf "%.7s" $commit.Commit.Hash}}]({{ replace $.URL "{{hash}}" $commit.Commit.Hash}})) {{end}}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
{{ end -}}
|
{{ end -}}`
|
||||||
|
const defaultChangelogTitle string = `v{{.Version}} ({{.Now.Format "2006-01-02"}})`
|
||||||
|
const defaultChangelog string = `# v{{$.Version}} ({{.Now.Format "2006-01-02"}})
|
||||||
|
{{ .Commits -}}
|
||||||
{{ if .HasDocker}}
|
{{ if .HasDocker}}
|
||||||
## Docker image
|
## Docker image
|
||||||
|
|
||||||
@@ -48,6 +50,16 @@ or
|
|||||||
`
|
`
|
||||||
|
|
||||||
type changelogContent struct {
|
type changelogContent struct {
|
||||||
|
Commits string
|
||||||
|
Version string
|
||||||
|
Now time.Time
|
||||||
|
Backtick string
|
||||||
|
HasDocker bool
|
||||||
|
HasDockerLatest bool
|
||||||
|
DockerRepository string
|
||||||
|
}
|
||||||
|
|
||||||
|
type commitsContent struct {
|
||||||
Commits map[string][]shared.AnalyzedCommit
|
Commits map[string][]shared.AnalyzedCommit
|
||||||
BreakingChanges []shared.AnalyzedCommit
|
BreakingChanges []shared.AnalyzedCommit
|
||||||
Order []string
|
Order []string
|
||||||
@@ -56,9 +68,6 @@ type changelogContent struct {
|
|||||||
Backtick string
|
Backtick string
|
||||||
HasURL bool
|
HasURL bool
|
||||||
URL string
|
URL string
|
||||||
HasDocker bool
|
|
||||||
HasDockerLatest bool
|
|
||||||
DockerRepository string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Changelog struct
|
//Changelog struct
|
||||||
@@ -108,7 +117,7 @@ func (c *Changelog) GenerateChanglog(templateConfig shared.ChangelogTemplateConf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
changelogContent := changelogContent{
|
commitsContent := commitsContent{
|
||||||
Version: templateConfig.Version,
|
Version: templateConfig.Version,
|
||||||
Commits: commitsPerScope,
|
Commits: commitsPerScope,
|
||||||
Now: c.releaseTime,
|
Now: c.releaseTime,
|
||||||
@@ -117,21 +126,52 @@ func (c *Changelog) GenerateChanglog(templateConfig shared.ChangelogTemplateConf
|
|||||||
Order: order,
|
Order: order,
|
||||||
HasURL: templateConfig.CommitURL != "",
|
HasURL: templateConfig.CommitURL != "",
|
||||||
URL: templateConfig.CommitURL,
|
URL: templateConfig.CommitURL,
|
||||||
|
}
|
||||||
|
|
||||||
|
changelogContent := changelogContent{
|
||||||
|
Version: templateConfig.Version,
|
||||||
|
Now: c.releaseTime,
|
||||||
|
Backtick: "`",
|
||||||
HasDocker: c.config.Changelog.Docker.Repository != "",
|
HasDocker: c.config.Changelog.Docker.Repository != "",
|
||||||
HasDockerLatest: c.config.Changelog.Docker.Latest,
|
HasDockerLatest: c.config.Changelog.Docker.Latest,
|
||||||
DockerRepository: c.config.Changelog.Docker.Repository,
|
DockerRepository: c.config.Changelog.Docker.Repository,
|
||||||
}
|
}
|
||||||
|
template := defaultChangelog
|
||||||
title, err := generateTemplate(defaultChangelogTitle, changelogContent)
|
if c.config.Changelog.TemplatePath != "" {
|
||||||
|
content, err := ioutil.ReadFile(c.config.Changelog.TemplatePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
content, err := generateTemplate(defaultChangelog, changelogContent)
|
template = string(content)
|
||||||
|
|
||||||
return &shared.GeneratedChangelog{Title: title, Content: content}, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateTemplate(text string, values changelogContent) (string, error) {
|
templateTitle := defaultChangelogTitle
|
||||||
|
if c.config.Changelog.TemplateTitle != "" {
|
||||||
|
templateTitle = c.config.Changelog.TemplateTitle
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("Render title")
|
||||||
|
renderedTitle, err := generateTemplate(templateTitle, changelogContent)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("Render commits")
|
||||||
|
renderedCommitList, err := generateTemplate(defaultCommitList, commitsContent)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Tracef("Commits %s", renderedCommitList)
|
||||||
|
|
||||||
|
changelogContent.Commits = renderedCommitList
|
||||||
|
log.Debugf("Render changelog")
|
||||||
|
renderedContent, err := generateTemplate(template, changelogContent)
|
||||||
|
|
||||||
|
return &shared.GeneratedChangelog{Title: renderedTitle, Content: renderedContent}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateTemplate(text string, values interface{}) (string, error) {
|
||||||
|
|
||||||
funcMap := template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
"replace": replace,
|
"replace": replace,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
// ChangelogConfig struct
|
// ChangelogConfig struct
|
||||||
type ChangelogConfig struct {
|
type ChangelogConfig struct {
|
||||||
PrintAll bool `yaml:"printAll,omitempty"`
|
PrintAll bool `yaml:"printAll,omitempty"`
|
||||||
Template string `yaml:"template,omitempty"`
|
TemplateTitle string `yaml:"title,omitempty"`
|
||||||
TemplatePath string `yaml:"templatePath,omitempty"`
|
TemplatePath string `yaml:"templatePath,omitempty"`
|
||||||
Docker ChangelogDocker `yaml:"docker,omitempty"`
|
Docker ChangelogDocker `yaml:"docker,omitempty"`
|
||||||
NPM ChangelogNPM `yaml:"npm,omitempty"`
|
NPM ChangelogNPM `yaml:"npm,omitempty"`
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ github:
|
|||||||
Branch: map[string]string{"add_git_releases": "alpha", "alpha": "alpha", "beta": "beta", "master": "release", "rc": "rc"},
|
Branch: map[string]string{"add_git_releases": "alpha", "alpha": "alpha", "beta": "beta", "master": "release", "rc": "rc"},
|
||||||
Changelog: config.ChangelogConfig{
|
Changelog: config.ChangelogConfig{
|
||||||
PrintAll: false,
|
PrintAll: false,
|
||||||
Template: "",
|
TemplateTitle: "",
|
||||||
TemplatePath: ""},
|
TemplatePath: ""},
|
||||||
Release: "github",
|
Release: "github",
|
||||||
GitHubProvider: config.GitHubProvider{
|
GitHubProvider: config.GitHubProvider{
|
||||||
@@ -92,20 +92,3 @@ github:
|
|||||||
}, result)
|
}, result)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// func TestWriteNotFound(t *testing.T) {
|
|
||||||
|
|
||||||
// err := cache.Write("notfound/dir", shared.ReleaseVersion{
|
|
||||||
// Last: shared.ReleaseVersionEntry{
|
|
||||||
// Commit: "12345",
|
|
||||||
// Version: createVersion("1.0.0"),
|
|
||||||
// },
|
|
||||||
// Next: shared.ReleaseVersionEntry{
|
|
||||||
// Commit: "12346",
|
|
||||||
// Version: createVersion("1.1.0"),
|
|
||||||
// },
|
|
||||||
// Branch: "master",
|
|
||||||
// })
|
|
||||||
// assert.Errorf(t, err, "Write non exsiting file")
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|||||||
Reference in New Issue
Block a user