You've already forked go-semantic-release
Merge remote-tracking branch 'origin/travis' into add_git_releases
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
commitFormat: angular
|
commitFormat: angular
|
||||||
branch:
|
branch:
|
||||||
master: release
|
master: release
|
||||||
travis: rc
|
rc: rc
|
||||||
beta: beta
|
beta: beta
|
||||||
alpha: alpha
|
alpha: alpha
|
||||||
changelog:
|
changelog:
|
||||||
print: all/compact
|
printAll: false
|
||||||
template: ''
|
template: ''
|
||||||
templatePath: ''
|
templatePath: ''
|
||||||
release: 'github'
|
release: 'github'
|
||||||
|
|||||||
2
README2.md
Normal file
2
README2.md
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
go build ./cmd/main.go && ./main.exe version next --path /f/Repro/ambassador/
|
||||||
|
go build ./cmd/main.go && ./main.exe --loglevel debug version set v1.1.1 --path /f/Repro/ambassador/
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/Nightapes/go-semantic-release/pkg/config"
|
"github.com/Nightapes/go-semantic-release/pkg/config"
|
||||||
@@ -24,6 +25,11 @@ var (
|
|||||||
setRepository = setCommand.Flag("repository", "Path to repository").String()
|
setRepository = setCommand.Flag("repository", "Path to repository").String()
|
||||||
setConfigPath = setCommand.Flag("config", "Path to config file").Default(".release.yml").String()
|
setConfigPath = setCommand.Flag("config", "Path to config file").Default(".release.yml").String()
|
||||||
setVersion = setCommand.Arg("version", "semver version").Required().String()
|
setVersion = setCommand.Arg("version", "semver version").Required().String()
|
||||||
|
|
||||||
|
getChangelog = app.Command("changelog", "Print changelog.")
|
||||||
|
getChangelogRepository = getChangelog.Flag("repository", "Path to repository").String()
|
||||||
|
getChangelogConfigPath = getChangelog.Flag("config", "Path to config file").Default(".release.yml").String()
|
||||||
|
getChangelogFile = getChangelog.Flag("file", "save changelog to file").Default("CHANGELOG.md").String()
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -32,10 +38,11 @@ func main() {
|
|||||||
case nextCommand.FullCommand():
|
case nextCommand.FullCommand():
|
||||||
setLoglevel(*loglevel)
|
setLoglevel(*loglevel)
|
||||||
s := semanticrelease.New(readConfig(nextConfigPath))
|
s := semanticrelease.New(readConfig(nextConfigPath))
|
||||||
err := s.GetNextVersion(*nextRepository, *nextForce)
|
version, err := s.GetNextVersion(*nextRepository, *nextForce)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
fmt.Println(version)
|
||||||
|
|
||||||
case setCommand.FullCommand():
|
case setCommand.FullCommand():
|
||||||
setLoglevel(*loglevel)
|
setLoglevel(*loglevel)
|
||||||
@@ -45,6 +52,13 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
case getChangelog.FullCommand():
|
||||||
|
setLoglevel(*loglevel)
|
||||||
|
s := semanticrelease.New(readConfig(getChangelogConfigPath))
|
||||||
|
err := s.GetChangelog(*getChangelogRepository, *getChangelogFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,24 +3,27 @@ package analyzer
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
||||||
|
"github.com/Nightapes/go-semantic-release/pkg/config"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
//Analyzer struct
|
//Analyzer struct
|
||||||
type Analyzer struct {
|
type Analyzer struct {
|
||||||
CommitFormat string
|
CommitFormat string
|
||||||
|
Config config.ChangelogConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
//Rules for commits
|
//Rule for commits
|
||||||
type Rules struct {
|
type Rule struct {
|
||||||
Tag string
|
Tag string
|
||||||
|
TagString string
|
||||||
Release string
|
Release string
|
||||||
Enabled bool
|
Changelog bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type analyzeCommit interface {
|
type analyzeCommit interface {
|
||||||
analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bool)
|
analyze(commit gitutil.Commit, tag Rule) (AnalyzedCommit, bool, error)
|
||||||
getRules() []Rules
|
getRules() []Rule
|
||||||
}
|
}
|
||||||
|
|
||||||
//AnalyzedCommit struct
|
//AnalyzedCommit struct
|
||||||
@@ -29,12 +32,16 @@ type AnalyzedCommit struct {
|
|||||||
ParsedMessage string
|
ParsedMessage string
|
||||||
Scope string
|
Scope string
|
||||||
ParsedBreakingChangeMessage string
|
ParsedBreakingChangeMessage string
|
||||||
|
Tag string
|
||||||
|
TagString string
|
||||||
|
Print bool
|
||||||
}
|
}
|
||||||
|
|
||||||
//New Analyzer struct for given commit format
|
//New Analyzer struct for given commit format
|
||||||
func New(format string) *Analyzer {
|
func New(format string, config config.ChangelogConfig) *Analyzer {
|
||||||
return &Analyzer{
|
return &Analyzer{
|
||||||
CommitFormat: format,
|
CommitFormat: format,
|
||||||
|
Config: config,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -45,7 +52,7 @@ func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit
|
|||||||
var commitAnalayzer analyzeCommit
|
var commitAnalayzer analyzeCommit
|
||||||
switch a.CommitFormat {
|
switch a.CommitFormat {
|
||||||
case "angular":
|
case "angular":
|
||||||
log.Infof("analyze angular format")
|
log.Debugf("Commit format set to angular")
|
||||||
commitAnalayzer = newAngular()
|
commitAnalayzer = newAngular()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,18 +60,29 @@ func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit
|
|||||||
analyzedCommits["major"] = make([]AnalyzedCommit, 0)
|
analyzedCommits["major"] = make([]AnalyzedCommit, 0)
|
||||||
analyzedCommits["minor"] = make([]AnalyzedCommit, 0)
|
analyzedCommits["minor"] = make([]AnalyzedCommit, 0)
|
||||||
analyzedCommits["patch"] = make([]AnalyzedCommit, 0)
|
analyzedCommits["patch"] = make([]AnalyzedCommit, 0)
|
||||||
|
analyzedCommits["none"] = make([]AnalyzedCommit, 0)
|
||||||
|
|
||||||
for _, commit := range commits {
|
for _, commit := range commits {
|
||||||
for _, rule := range commitAnalayzer.getRules() {
|
for _, rule := range commitAnalayzer.getRules() {
|
||||||
analyzedCommit, hasBreakingChange := commitAnalayzer.analyze(commit, rule.Tag)
|
analyzedCommit, hasBreakingChange, err := commitAnalayzer.analyze(commit, rule)
|
||||||
|
if err == nil {
|
||||||
|
if a.Config.PrintAll {
|
||||||
|
analyzedCommit.Print = true
|
||||||
|
} else {
|
||||||
|
analyzedCommit.Print = rule.Changelog
|
||||||
|
}
|
||||||
if hasBreakingChange {
|
if hasBreakingChange {
|
||||||
analyzedCommits["major"] = append(analyzedCommits["major"], analyzedCommit)
|
analyzedCommits["major"] = append(analyzedCommits["major"], analyzedCommit)
|
||||||
} else {
|
} else {
|
||||||
analyzedCommits[rule.Release] = append(analyzedCommits[rule.Release], analyzedCommit)
|
analyzedCommits[rule.Release] = append(analyzedCommits[rule.Release], analyzedCommit)
|
||||||
}
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debugf("Analyzed commits: major=%d minor=%d patch=%d none=%d", len(analyzedCommits["major"]), len(analyzedCommits["minor"]), len(analyzedCommits["patch"]), len(analyzedCommits["none"]))
|
||||||
|
|
||||||
return analyzedCommits
|
return analyzedCommits
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,53 +2,93 @@
|
|||||||
package analyzer
|
package analyzer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type angular struct {
|
type angular struct {
|
||||||
rules []Rules
|
rules []Rule
|
||||||
regex string
|
regex string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAngular() *angular {
|
func newAngular() *angular {
|
||||||
return &angular{
|
return &angular{
|
||||||
regex: `(TAG)(?:\((.*)\))?: (.*)`,
|
regex: `(TAG)(?:\((.*)\))?: (.*)`,
|
||||||
rules: []Rules{
|
rules: []Rule{
|
||||||
{
|
{
|
||||||
Tag: "feat",
|
Tag: "feat",
|
||||||
|
TagString: "Features",
|
||||||
Release: "minor",
|
Release: "minor",
|
||||||
Enabled: true,
|
Changelog: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Tag: "fix",
|
Tag: "fix",
|
||||||
|
TagString: "Bug fixes",
|
||||||
Release: "patch",
|
Release: "patch",
|
||||||
Enabled: true,
|
Changelog: true,
|
||||||
}, {
|
}, {
|
||||||
Tag: "perf",
|
Tag: "perf",
|
||||||
|
TagString: "Performance improvments",
|
||||||
Release: "patch",
|
Release: "patch",
|
||||||
Enabled: true,
|
Changelog: true,
|
||||||
|
}, {
|
||||||
|
Tag: "docs",
|
||||||
|
TagString: "Documentation changes",
|
||||||
|
Release: "none",
|
||||||
|
Changelog: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Tag: "style",
|
||||||
|
TagString: "Style",
|
||||||
|
Release: "none",
|
||||||
|
Changelog: false,
|
||||||
|
}, {
|
||||||
|
Tag: "refactor",
|
||||||
|
TagString: "Code refactor",
|
||||||
|
Release: "none",
|
||||||
|
Changelog: false,
|
||||||
|
}, {
|
||||||
|
Tag: "test",
|
||||||
|
TagString: "Testing",
|
||||||
|
Release: "none",
|
||||||
|
Changelog: false,
|
||||||
|
}, {
|
||||||
|
Tag: "chore",
|
||||||
|
TagString: "Changes to the build process or auxiliary tools and libraries such as documentation generation",
|
||||||
|
Release: "none",
|
||||||
|
Changelog: false,
|
||||||
|
}, {
|
||||||
|
Tag: "build",
|
||||||
|
TagString: "Changes to ci config",
|
||||||
|
Release: "none",
|
||||||
|
Changelog: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *angular) getRules() []Rules {
|
func (a *angular) getRules() []Rule {
|
||||||
return a.rules
|
return a.rules
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *angular) analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bool) {
|
func (a *angular) analyze(commit gitutil.Commit, rule Rule) (AnalyzedCommit, bool, error) {
|
||||||
|
|
||||||
analyzed := AnalyzedCommit{
|
analyzed := AnalyzedCommit{
|
||||||
Commit: commit,
|
Commit: commit,
|
||||||
|
Tag: rule.Tag,
|
||||||
|
TagString: rule.TagString,
|
||||||
}
|
}
|
||||||
|
|
||||||
re := regexp.MustCompile(strings.Replace(a.regex, "TAG", tag, -1))
|
re := regexp.MustCompile(strings.Replace(a.regex, "TAG", rule.Tag, -1))
|
||||||
matches := re.FindAllStringSubmatch(commit.Message+" "+commit.Message, -1)
|
matches := re.FindAllStringSubmatch(commit.Message, -1)
|
||||||
if len(matches) >= 1 {
|
if len(matches) >= 1 {
|
||||||
if len(matches[0]) >= 3 {
|
if len(matches[0]) >= 3 {
|
||||||
|
|
||||||
analyzed.Scope = matches[0][2]
|
analyzed.Scope = matches[0][2]
|
||||||
|
|
||||||
message := strings.Join(matches[0][3:], "")
|
message := strings.Join(matches[0][3:], "")
|
||||||
@@ -56,14 +96,17 @@ func (a *angular) analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bo
|
|||||||
|
|
||||||
if len(splitted) == 1 {
|
if len(splitted) == 1 {
|
||||||
analyzed.ParsedMessage = splitted[0]
|
analyzed.ParsedMessage = splitted[0]
|
||||||
return analyzed, false
|
log.Tracef("%s: found %s", commit.Message, rule.Tag)
|
||||||
|
return analyzed, false, nil
|
||||||
}
|
}
|
||||||
analyzed.ParsedMessage = splitted[0]
|
analyzed.ParsedMessage = splitted[0]
|
||||||
analyzed.ParsedBreakingChangeMessage = splitted[1]
|
analyzed.ParsedBreakingChangeMessage = splitted[1]
|
||||||
return analyzed, true
|
log.Tracef(" %s, BREAKING CHANGE found", commit.Message)
|
||||||
|
return analyzed, true, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return analyzed, false
|
log.Tracef("%s does not match %s, skip", commit.Message, rule.Tag)
|
||||||
|
return analyzed, false, fmt.Errorf("Not found")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
82
internal/changelog/changelog.go
Normal file
82
internal/changelog/changelog.go
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package changelog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"text/template"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/analyzer"
|
||||||
|
"github.com/Nightapes/go-semantic-release/pkg/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
const defaultChangelogTitle string = `v{{.Version}} ({{.Now.Format "2006-01-02"}})`
|
||||||
|
const defaultChangelog string = `{{ $version := .Version -}}
|
||||||
|
{{ $backtick := .Backtick -}}
|
||||||
|
# v{{.Version}} ({{.Now.Format "2006-01-02"}})
|
||||||
|
{{ range $key, $commits := .Commits }}
|
||||||
|
### {{ $key }}
|
||||||
|
|
||||||
|
{{range $index,$commit := $commits}}* **{{$backtick}}{{$commit.Scope}}:{{$backtick}}** {{$commit.ParsedMessage}}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
|
`
|
||||||
|
|
||||||
|
type changelogContent struct {
|
||||||
|
Commits map[string][]analyzer.AnalyzedCommit
|
||||||
|
Version string
|
||||||
|
Now time.Time
|
||||||
|
Backtick string
|
||||||
|
}
|
||||||
|
|
||||||
|
//CommitFormat struct
|
||||||
|
type Changelog struct {
|
||||||
|
config *config.ReleaseConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
//New Changelog struct for generating changelog from commits
|
||||||
|
func New(config *config.ReleaseConfig) *Changelog {
|
||||||
|
return &Changelog{
|
||||||
|
config: config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateChanglog from given commits
|
||||||
|
func (c *Changelog) GenerateChanglog(version string, analyzedCommits map[string][]analyzer.AnalyzedCommit) (string, string, error) {
|
||||||
|
|
||||||
|
commitsPerScope := map[string][]analyzer.AnalyzedCommit{}
|
||||||
|
for _, commits := range analyzedCommits {
|
||||||
|
for _, commit := range commits {
|
||||||
|
if commit.Print {
|
||||||
|
if _, ok := commitsPerScope[commit.TagString]; !ok {
|
||||||
|
commitsPerScope[commit.TagString] = make([]analyzer.AnalyzedCommit, 0)
|
||||||
|
}
|
||||||
|
commitsPerScope[commit.TagString] = append(commitsPerScope[commit.TagString], commit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changelogContent := changelogContent{
|
||||||
|
Version: version,
|
||||||
|
Commits: commitsPerScope,
|
||||||
|
Now: time.Now(),
|
||||||
|
Backtick: "`",
|
||||||
|
}
|
||||||
|
|
||||||
|
title, err := generateTemplate(defaultChangelogTitle, changelogContent)
|
||||||
|
content, err := generateTemplate(defaultChangelog, changelogContent)
|
||||||
|
|
||||||
|
return title, content, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateTemplate(text string, values changelogContent) (string, error) {
|
||||||
|
var tpl bytes.Buffer
|
||||||
|
tmpl, err := template.New("template").Parse(text)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
err = tmpl.Execute(&tpl, values)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
return tpl.String(), nil
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/Masterminds/semver"
|
"github.com/Masterminds/semver"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gopkg.in/src-d/go-git.v4"
|
"gopkg.in/src-d/go-git.v4"
|
||||||
|
"gopkg.in/src-d/go-git.v4/plumbing"
|
||||||
"gopkg.in/src-d/go-git.v4/plumbing/object"
|
"gopkg.in/src-d/go-git.v4/plumbing/object"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -62,23 +63,27 @@ func (g *GitUtil) GetBranch() (string, error) {
|
|||||||
// GetLastVersion from git tags
|
// GetLastVersion from git tags
|
||||||
func (g *GitUtil) GetLastVersion() (*semver.Version, string, error) {
|
func (g *GitUtil) GetLastVersion() (*semver.Version, string, error) {
|
||||||
|
|
||||||
log.Debugf("GetLastVersion")
|
var tags []*semver.Version
|
||||||
|
|
||||||
|
gitTags, err := g.Repository.Tags()
|
||||||
|
|
||||||
tagObjects, err := g.Repository.TagObjects()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
var tags []*semver.Version
|
err = gitTags.ForEach(func(p *plumbing.Reference) error {
|
||||||
|
v, err := semver.NewVersion(p.Name().Short())
|
||||||
err = tagObjects.ForEach(func(t *object.Tag) error {
|
log.Tracef("%+v", p.Name().Short())
|
||||||
v, err := semver.NewVersion(t.Name)
|
if err == nil {
|
||||||
|
_, err := g.Repository.TagObject(p.Hash())
|
||||||
if err != nil {
|
if err == nil {
|
||||||
log.Debugf("Tag %s is not a valid version, skip", t.Name)
|
log.Debugf("Add tag %s", p.Name().Short())
|
||||||
} else {
|
|
||||||
log.Debugf("Add tag %s", t.Name)
|
|
||||||
tags = append(tags, v)
|
tags = append(tags, v)
|
||||||
|
} else {
|
||||||
|
log.Debugf("Found tag %s, but is not annotated, skip", err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Debugf("Tag %s is not a valid version, skip", p.Name().Short())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@@ -113,7 +118,6 @@ func (g *GitUtil) GetLastVersion() (*semver.Version, string, error) {
|
|||||||
// GetCommits from git hash to HEAD
|
// GetCommits from git hash to HEAD
|
||||||
func (g *GitUtil) GetCommits(lastTagHash string) ([]Commit, error) {
|
func (g *GitUtil) GetCommits(lastTagHash string) ([]Commit, error) {
|
||||||
|
|
||||||
log.Printf("Read head")
|
|
||||||
ref, err := g.Repository.Head()
|
ref, err := g.Repository.Head()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -129,7 +133,7 @@ func (g *GitUtil) GetCommits(lastTagHash string) ([]Commit, error) {
|
|||||||
|
|
||||||
err = cIter.ForEach(func(c *object.Commit) error {
|
err = cIter.ForEach(func(c *object.Commit) error {
|
||||||
if c.Hash.String() == lastTagHash {
|
if c.Hash.String() == lastTagHash {
|
||||||
log.Infof("%s == %s", c.Hash.String(), lastTagHash)
|
log.Debugf("Found commit with hash %s, will stop here", c.Hash.String())
|
||||||
foundEnd = true
|
foundEnd = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
// ChangelogConfig struct
|
// ChangelogConfig struct
|
||||||
type ChangelogConfig struct {
|
type ChangelogConfig struct {
|
||||||
Print string `yaml:"print,omitempty"`
|
PrintAll bool `yaml:"printAll,omitempty"`
|
||||||
Template string `yaml:"template,omitempty"`
|
Template string `yaml:"template,omitempty"`
|
||||||
TemplatePath string `yaml:"templatePath,omitempty"`
|
TemplatePath string `yaml:"templatePath,omitempty"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,14 @@
|
|||||||
package semanticrelease
|
package semanticrelease
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"io/ioutil"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/Masterminds/semver"
|
"github.com/Masterminds/semver"
|
||||||
"github.com/Nightapes/go-semantic-release/internal/analyzer"
|
"github.com/Nightapes/go-semantic-release/internal/analyzer"
|
||||||
"github.com/Nightapes/go-semantic-release/internal/cache"
|
"github.com/Nightapes/go-semantic-release/internal/cache"
|
||||||
|
"github.com/Nightapes/go-semantic-release/internal/changelog"
|
||||||
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
"github.com/Nightapes/go-semantic-release/internal/gitutil"
|
||||||
"github.com/Nightapes/go-semantic-release/pkg/config"
|
"github.com/Nightapes/go-semantic-release/pkg/config"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@@ -27,15 +28,15 @@ func New(c *config.ReleaseConfig) *SemanticRelease {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetNextVersion from .version or calculate new from commits
|
// GetNextVersion from .version or calculate new from commits
|
||||||
func (s *SemanticRelease) GetNextVersion(repro string, force bool) error {
|
func (s *SemanticRelease) GetNextVersion(repro string, force bool) (string, error) {
|
||||||
util, err := gitutil.New(repro)
|
util, err := gitutil.New(repro)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
hash, err := util.GetHash()
|
hash, err := util.GetHash()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Ignore .version file if exits, %t", force)
|
log.Debugf("Ignore .version file if exits, %t", force)
|
||||||
@@ -43,89 +44,67 @@ func (s *SemanticRelease) GetNextVersion(repro string, force bool) error {
|
|||||||
content, err := cache.Read()
|
content, err := cache.Read()
|
||||||
|
|
||||||
if err == nil && content.Commit == hash {
|
if err == nil && content.Commit == hash {
|
||||||
fmt.Printf(content.NextVersion)
|
log.Infof("Found cache, will return cached version %s", content.NextVersion)
|
||||||
return nil
|
return content.NextVersion, err
|
||||||
}
|
}
|
||||||
log.Debugf("Mismatch git and version file %s - %s", content.Commit, hash)
|
log.Debugf("Mismatch git and version file %s - %s", content.Commit, hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
lastVersion, lastVersionHash, err := util.GetLastVersion()
|
lastVersion, lastVersionHash, err := util.GetLastVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
|
var newVersion semver.Version
|
||||||
|
|
||||||
if lastVersion == nil {
|
if lastVersion == nil {
|
||||||
defaultVersion, _ := semver.NewVersion("1.0.0")
|
defaultVersion, _ := semver.NewVersion("1.0.0")
|
||||||
err := s.SetVersion(defaultVersion.String(), repro)
|
newVersion = *defaultVersion
|
||||||
if err != nil {
|
} else {
|
||||||
return err
|
newVersion = *lastVersion
|
||||||
}
|
|
||||||
fmt.Printf("%s", defaultVersion.String())
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commits, err := util.GetCommits(lastVersionHash)
|
commits, err := util.GetCommits(lastVersionHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Found %d commits till last release", len(commits))
|
log.Debugf("Found %d commits till last release", len(commits))
|
||||||
|
|
||||||
a := analyzer.New("angular")
|
a := analyzer.New(s.config.CommitFormat, s.config.Changelog)
|
||||||
result := a.Analyze(commits)
|
result := a.Analyze(commits)
|
||||||
|
|
||||||
var newVersion semver.Version
|
|
||||||
|
|
||||||
currentBranch, err := util.GetBranch()
|
currentBranch, err := util.GetBranch()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return "", err
|
||||||
}
|
|
||||||
newVersion = *lastVersion
|
|
||||||
if lastVersion.Prerelease() == "" {
|
|
||||||
if len(result["major"]) > 0 {
|
|
||||||
newVersion = lastVersion.IncMajor()
|
|
||||||
} else if len(result["minor"]) > 0 {
|
|
||||||
newVersion = lastVersion.IncMinor()
|
|
||||||
} else if len(result["patch"]) > 0 {
|
|
||||||
newVersion = lastVersion.IncPatch()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Test %+v", s.config)
|
|
||||||
for branch, releaseType := range s.config.Branch {
|
for branch, releaseType := range s.config.Branch {
|
||||||
if currentBranch == branch || strings.HasPrefix(currentBranch, branch) {
|
if currentBranch == branch || strings.HasPrefix(currentBranch, branch) {
|
||||||
log.Debugf("Found branch config for branch %s with release type %s", currentBranch, releaseType)
|
log.Debugf("Found branch config for branch %s with release type %s", currentBranch, releaseType)
|
||||||
switch releaseType {
|
switch releaseType {
|
||||||
case "rc":
|
case "rc", "beta", "alpha":
|
||||||
if newVersion.Prerelease() == "" || !strings.HasPrefix(newVersion.Prerelease(), "rc") {
|
newVersion = incPrerelease(releaseType, newVersion)
|
||||||
newVersion, _ = newVersion.SetPrerelease("rc.0")
|
case "release":
|
||||||
} else {
|
if len(result["major"]) > 0 {
|
||||||
parts := strings.Split(newVersion.Prerelease(), ".")
|
newVersion = newVersion.IncMajor()
|
||||||
if len(parts) == 2 {
|
} else if len(result["minor"]) > 0 {
|
||||||
i, err := strconv.Atoi(parts[1])
|
newVersion = newVersion.IncMinor()
|
||||||
|
} else if len(result["patch"]) > 0 {
|
||||||
|
newVersion = newVersion.IncPatch()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("New version %s -> %s", lastVersion.String(), newVersion.String())
|
||||||
|
err = saveToCache(util, lastVersion, &newVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
newVersion, _ = newVersion.SetPrerelease("rc.0")
|
return "", err
|
||||||
log.Warnf("Could not parse release tag %s, use version %s", newVersion.Prerelease(), newVersion.String())
|
|
||||||
} else {
|
|
||||||
newVersion, _ = newVersion.SetPrerelease("rc." + strconv.Itoa((i + 1)))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
newVersion, _ = newVersion.SetPrerelease("rc.0")
|
|
||||||
log.Warnf("Could not parse release tag %s, use version %s", newVersion.Prerelease(), newVersion.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
c := changelog.New(s.config)
|
||||||
|
c.GenerateChanglog(newVersion.String(), result)
|
||||||
|
|
||||||
}
|
return newVersion.String(), err
|
||||||
}
|
|
||||||
|
|
||||||
err = s.SetVersion(newVersion.String(), repro)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Printf("%s", newVersion.String())
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//SetVersion for git repository
|
//SetVersion for git repository
|
||||||
@@ -141,6 +120,16 @@ func (s *SemanticRelease) SetVersion(version string, repro string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastVersion, _, err := util.GetLastVersion()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return saveToCache(util, lastVersion, newVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
func saveToCache(util *gitutil.GitUtil, lastVersion *semver.Version, nextVersion *semver.Version) error {
|
||||||
|
|
||||||
hash, err := util.GetHash()
|
hash, err := util.GetHash()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -153,18 +142,72 @@ func (s *SemanticRelease) SetVersion(version string, repro string) error {
|
|||||||
|
|
||||||
newVersionContent := cache.VersionFileContent{
|
newVersionContent := cache.VersionFileContent{
|
||||||
Commit: hash,
|
Commit: hash,
|
||||||
NextVersion: newVersion.String(),
|
NextVersion: nextVersion.String(),
|
||||||
Branch: branch,
|
Branch: branch,
|
||||||
}
|
}
|
||||||
|
|
||||||
lastVersion, _, err := util.GetLastVersion()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if lastVersion != nil {
|
if lastVersion != nil {
|
||||||
newVersionContent.Version = lastVersion.String()
|
newVersionContent.Version = lastVersion.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debugf("Save %s with hash %s to cache", nextVersion.String(), hash)
|
||||||
return cache.Write(newVersionContent)
|
return cache.Write(newVersionContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func incPrerelease(preReleaseType string, version semver.Version) semver.Version {
|
||||||
|
defaultPrerelease := preReleaseType + ".0"
|
||||||
|
if version.Prerelease() == "" || !strings.HasPrefix(version.Prerelease(), preReleaseType) {
|
||||||
|
version, _ = version.SetPrerelease(defaultPrerelease)
|
||||||
|
} else {
|
||||||
|
parts := strings.Split(version.Prerelease(), ".")
|
||||||
|
if len(parts) == 2 {
|
||||||
|
i, err := strconv.Atoi(parts[1])
|
||||||
|
if err != nil {
|
||||||
|
version, _ = version.SetPrerelease(defaultPrerelease)
|
||||||
|
log.Warnf("Could not parse release tag %s, use version %s", version.Prerelease(), version.String())
|
||||||
|
} else {
|
||||||
|
version, _ = version.SetPrerelease(preReleaseType + "." + strconv.Itoa((i + 1)))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
version, _ = version.SetPrerelease(defaultPrerelease)
|
||||||
|
log.Warnf("Could not parse release tag %s, use version %s", version.Prerelease(), version.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return version
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetChangelog from last version till now
|
||||||
|
func (s *SemanticRelease) GetChangelog(repro, file string) error {
|
||||||
|
nextVersion, err := s.GetNextVersion(repro, false)
|
||||||
|
if err != nil {
|
||||||
|
log.Debugf("Could not get next version")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
util, err := gitutil.New(repro)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, lastVersionHash, err := util.GetLastVersion()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
commits, err := util.GetCommits(lastVersionHash)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("Found %d commits till last release", len(commits))
|
||||||
|
|
||||||
|
a := analyzer.New(s.config.CommitFormat, s.config.Changelog)
|
||||||
|
result := a.Analyze(commits)
|
||||||
|
|
||||||
|
c := changelog.New(s.config)
|
||||||
|
_, content, err := c.GenerateChanglog(nextVersion, result)
|
||||||
|
|
||||||
|
return ioutil.WriteFile(file, []byte(content), 0644)
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user