From dc4d1c581a6009641b6b0881ecde8c9d2ca84e91 Mon Sep 17 00:00:00 2001 From: maulik13 Date: Tue, 16 Feb 2021 15:25:34 +0100 Subject: [PATCH] feat(analyzer): update AnalyzedCommit to add flexibility in parsing a message This provides flexibility of parsing and rendering structured messages with more detail in the changelog and helps extract metadata from the message. The new structure can be used to split a message in multiple blocks (e.g. footer) --- internal/analyzer/analyzer.go | 71 +++++++++++++++++--- internal/analyzer/analyzer_test.go | 2 +- internal/analyzer/angular.go | 13 ++-- internal/analyzer/angular_test.go | 4 +- internal/analyzer/conventional.go | 86 +++++++++++++++++++------ internal/analyzer/conventional_test.go | 83 +++++++++++++++++++++++- internal/cache/cache_test.go | 2 + internal/changelog/changelog.go | 3 +- internal/changelog/changelog_test.go | 41 +++++++++++- internal/shared/shared.go | 11 +++- pkg/config/config.go | 6 ++ pkg/config/config_test.go | 1 + pkg/semanticrelease/semantic-release.go | 2 +- 13 files changed, 284 insertions(+), 41 deletions(-) diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go index 17fc4a5..3cffc49 100644 --- a/internal/analyzer/analyzer.go +++ b/internal/analyzer/analyzer.go @@ -3,6 +3,8 @@ package analyzer import ( "fmt" + "regexp" + "strings" "github.com/Nightapes/go-semantic-release/internal/shared" "github.com/Nightapes/go-semantic-release/pkg/config" @@ -11,8 +13,9 @@ import ( // Analyzer struct type Analyzer struct { - analyzeCommits analyzeCommits - Config config.ChangelogConfig + analyzeCommits analyzeCommits + ChangelogConfig config.ChangelogConfig + AnalyzerConfig config.AnalyzerConfig } // Rule for commits @@ -24,14 +27,15 @@ type Rule struct { } type analyzeCommits interface { - analyze(commit shared.Commit, tag Rule) (*shared.AnalyzedCommit, bool) + analyze(commit shared.Commit, tag Rule) *shared.AnalyzedCommit getRules() []Rule } // New Analyzer struct for given commit format -func New(format string, config config.ChangelogConfig) (*Analyzer, error) { +func New(format string, analyzerConfig config.AnalyzerConfig, chglogConfig config.ChangelogConfig) (*Analyzer, error) { analyzer := &Analyzer{ - Config: config, + AnalyzerConfig: analyzerConfig, + ChangelogConfig: chglogConfig, } switch format { @@ -39,7 +43,7 @@ func New(format string, config config.ChangelogConfig) (*Analyzer, error) { analyzer.analyzeCommits = newAngular() log.Debugf("Commit format set to %s", ANGULAR) case CONVENTIONAL: - analyzer.analyzeCommits = newConventional() + analyzer.analyzeCommits = newConventional(analyzerConfig) log.Debugf("Commit format set to %s", CONVENTIONAL) default: return nil, fmt.Errorf("invalid commit format: %s", format) @@ -62,14 +66,14 @@ func (a *Analyzer) Analyze(commits []shared.Commit) map[shared.Release][]shared. for _, commit := range commits { for _, rule := range a.analyzeCommits.getRules() { - analyzedCommit, hasBreakingChange := a.analyzeCommits.analyze(commit, rule) + analyzedCommit := a.analyzeCommits.analyze(commit, rule) if analyzedCommit == nil { continue } - if a.Config.PrintAll || rule.Changelog { + if a.ChangelogConfig.PrintAll || rule.Changelog { analyzedCommit.Print = true } - if hasBreakingChange { + if analyzedCommit.IsBreaking { analyzedCommits["major"] = append(analyzedCommits["major"], *analyzedCommit) break } @@ -80,3 +84,52 @@ func (a *Analyzer) Analyze(commits []shared.Commit) map[shared.Release][]shared. 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 } + +func getMessageParts(msg string) (header string, bodyBlocks []string){ + firstSplit := strings.SplitN(msg, "\n", 2) + header = firstSplit[0] + bodyBlocks = make([]string, 0) + + if len(firstSplit) < 2 { + return + } + // Trim and then split by a blank line + remaining := strings.Trim(firstSplit[1], "\n") + bodyBlocks = strings.Split(remaining, "\n\n") + + return +} + +func parseMessageBlock(msg string, prefixes []string) shared.MessageBlock { + for _, prefix := range prefixes { + if !strings.HasPrefix(msg, prefix + ":") { + continue + } + content := strings.Replace(msg, prefix+":", "", 1) + return shared.MessageBlock{ + Label: prefix, + Content: strings.TrimSpace(content), + } + } + return shared.MessageBlock{ + Label: "", + Content: msg, + } +} + +// +// getRegexMatchedMap will match a regex with named groups and map the matching +// results to corresponding group names +// +func getRegexMatchedMap(regEx, url string) (paramsMap map[string]string) { + var compRegEx = regexp.MustCompile(regEx) + match := compRegEx.FindStringSubmatch(url) + + paramsMap = make(map[string]string) + for i, name := range compRegEx.SubexpNames() { + if i > 0 && i <= len(match) { + paramsMap[name] = match[i] + } + } + return paramsMap +} diff --git a/internal/analyzer/analyzer_test.go b/internal/analyzer/analyzer_test.go index 0002a73..d78cda4 100644 --- a/internal/analyzer/analyzer_test.go +++ b/internal/analyzer/analyzer_test.go @@ -10,7 +10,7 @@ import ( func TestAnalyzer(t *testing.T) { - _, err := analyzer.New("unknown", config.ChangelogConfig{}) + _, err := analyzer.New("unknown", config.AnalyzerConfig{}, config.ChangelogConfig{}) assert.Error(t, err) } diff --git a/internal/analyzer/angular.go b/internal/analyzer/angular.go index b7c3784..cf9e348 100644 --- a/internal/analyzer/angular.go +++ b/internal/analyzer/angular.go @@ -86,12 +86,12 @@ func (a *angular) getRules() []Rule { return a.rules } -func (a *angular) analyze(commit shared.Commit, rule Rule) (*shared.AnalyzedCommit, bool) { +func (a *angular) analyze(commit shared.Commit, rule Rule) *shared.AnalyzedCommit { re := regexp.MustCompile(strings.Replace(a.regex, "TAG", rule.Tag, -1)) matches := re.FindStringSubmatch(commit.Message) if matches == nil { a.log.Tracef("%s does not match %s, skip", commit.Message, rule.Tag) - return nil, false + return nil } analyzed := &shared.AnalyzedCommit{ @@ -105,18 +105,21 @@ func (a *angular) analyze(commit shared.Commit, rule Rule) (*shared.AnalyzedComm if !strings.Contains(message, "BREAKING CHANGE:") { analyzed.ParsedMessage = strings.Trim(message, " ") a.log.Tracef("%s: found %s", commit.Message, rule.Tag) - return analyzed, false + return analyzed } a.log.Tracef(" %s, BREAKING CHANGE found", commit.Message) breakingChange := strings.SplitN(message, "BREAKING CHANGE:", 2) + analyzed.IsBreaking = true + if len(breakingChange) > 1 { analyzed.ParsedMessage = strings.TrimSpace(breakingChange[0]) analyzed.ParsedBreakingChangeMessage = strings.TrimSpace(breakingChange[1]) - return analyzed, true + + return analyzed } analyzed.ParsedBreakingChangeMessage = breakingChange[0] - return analyzed, true + return analyzed } diff --git a/internal/analyzer/angular_test.go b/internal/analyzer/angular_test.go index 250d5aa..527c2f6 100644 --- a/internal/analyzer/angular_test.go +++ b/internal/analyzer/angular_test.go @@ -75,6 +75,7 @@ func TestAngular(t *testing.T) { TagString: "Features", Print: true, ParsedBreakingChangeMessage: "change api to v2", + IsBreaking: true, }, }, "patch": {}, @@ -135,6 +136,7 @@ func TestAngular(t *testing.T) { TagString: "Features", Print: true, ParsedBreakingChangeMessage: "change api to v2", + IsBreaking: true, }, }, "patch": {}, @@ -212,7 +214,7 @@ func TestAngular(t *testing.T) { }, } - angular, err := analyzer.New("angular", config.ChangelogConfig{}) + angular, err := analyzer.New("angular", config.AnalyzerConfig{}, config.ChangelogConfig{}) assert.NoError(t, err) for _, test := range testConfigs { diff --git a/internal/analyzer/conventional.go b/internal/analyzer/conventional.go index 4486a48..1fa448e 100644 --- a/internal/analyzer/conventional.go +++ b/internal/analyzer/conventional.go @@ -2,7 +2,7 @@ package analyzer import ( - "regexp" + "github.com/Nightapes/go-semantic-release/pkg/config" "strings" log "github.com/sirupsen/logrus" @@ -14,14 +14,18 @@ type conventional struct { rules []Rule regex string log *log.Entry + config config.AnalyzerConfig } // CONVENTIONAL identifier const CONVENTIONAL = "conventional" +const breakingChangeKeywords = "BREAKING CHANGE" +const breakingChangePrefix = breakingChangeKeywords + ":" -func newConventional() *conventional { +func newConventional(config config.AnalyzerConfig) *conventional { return &conventional{ - regex: `^(TAG)(?:\((.*)\))?(\!)?: (?s)(.*)`, + config: config, + regex: `^(?P\w*)(?:\((?P.*)\))?(?P\!)?: (?P.*)`, log: log.WithField("analyzer", CONVENTIONAL), rules: []Rule{ { @@ -86,37 +90,79 @@ func (a *conventional) getRules() []Rule { return a.rules } -func (a *conventional) analyze(commit shared.Commit, rule Rule) (*shared.AnalyzedCommit, bool) { - re := regexp.MustCompile(strings.Replace(a.regex, "TAG", rule.Tag, -1)) - matches := re.FindStringSubmatch(commit.Message) - if matches == nil { +func (a *conventional) analyze(commit shared.Commit, rule Rule) *shared.AnalyzedCommit { + prefixes := append(a.config.BlockPrefixes, breakingChangeKeywords) + + header, txtBlocks := getMessageParts(commit.Message) + matches := getRegexMatchedMap(a.regex, header) + + if len(matches) == 0 || matches["type"] != rule.Tag{ a.log.Tracef("%s does not match %s, skip", commit.Message, rule.Tag) - return nil, false + return nil + } + + msgBlockMap := make(map[string][]shared.MessageBlock) + footer := "" + if len(txtBlocks) > 0 { + bodyCount := len(txtBlocks)-1 + if len(txtBlocks) == 1 { + bodyCount = 1 + } + bodyTxtBlocks := txtBlocks[0:bodyCount] + if len(txtBlocks) > 1{ + footer = txtBlocks[len(txtBlocks)-1] + } + msgBlockMap["body"] = getMessageBlocks(bodyTxtBlocks, prefixes) + + if len(footer) > 0{ + footerLines := strings.Split(footer, "\n") + msgBlockMap["footer"] = getMessageBlocks(footerLines, prefixes) + } } analyzed := &shared.AnalyzedCommit{ - Commit: commit, - Tag: rule.Tag, - TagString: rule.TagString, - Scope: shared.Scope(matches[2]), + Commit: commit, + Tag: rule.Tag, + TagString: rule.TagString, + Scope: shared.Scope(matches["scope"]), + Subject: strings.TrimSpace(matches["subject"]), + MessageBlocks: msgBlockMap, } - message := strings.Join(matches[4:], "") - if matches[3] == "" && !strings.Contains(message, "BREAKING CHANGE:") { - analyzed.ParsedMessage = strings.Trim(message, " ") + isBreaking := matches["breaking"] == "!" || strings.Contains(commit.Message, breakingChangePrefix) + analyzed.IsBreaking = isBreaking + + oldMsgSplit := strings.SplitN(commit.Message, "\n", 2) + originalBodyBlock := "" + if len(oldMsgSplit) > 1 { + originalBodyBlock = oldMsgSplit[1] + } + oldFormatMessage := strings.TrimSpace(matches["subject"] + "\n" + originalBodyBlock) + if !isBreaking { + analyzed.ParsedMessage = strings.Trim(oldFormatMessage, " ") a.log.Tracef("%s: found %s", commit.Message, rule.Tag) - return analyzed, false + return analyzed } a.log.Infof(" %s, BREAKING CHANGE found", commit.Message) - breakingChange := strings.SplitN(message, "BREAKING CHANGE:", 2) + breakingChange := strings.SplitN(oldFormatMessage, breakingChangePrefix, 2) if len(breakingChange) > 1 { analyzed.ParsedMessage = strings.TrimSpace(breakingChange[0]) analyzed.ParsedBreakingChangeMessage = strings.TrimSpace(breakingChange[1]) - return analyzed, true + } else { + analyzed.ParsedBreakingChangeMessage = breakingChange[0] } - analyzed.ParsedBreakingChangeMessage = breakingChange[0] - return analyzed, true + return analyzed } + +func getMessageBlocks(txtArray, prefixes []string) []shared.MessageBlock { + blocks := make([]shared.MessageBlock, len(txtArray)) + for i, line := range txtArray{ + blocks[i] = parseMessageBlock(line, prefixes) + } + return blocks +} + + diff --git a/internal/analyzer/conventional_test.go b/internal/analyzer/conventional_test.go index ca780f0..8d3ffcd 100644 --- a/internal/analyzer/conventional_test.go +++ b/internal/analyzer/conventional_test.go @@ -30,6 +30,8 @@ func TestConventional(t *testing.T) { ParsedMessage: "my first commit", Tag: "feat", TagString: "Features", + Subject: "my first commit", + MessageBlocks: map[string][]shared.MessageBlock{}, Print: true, }, { @@ -42,6 +44,8 @@ func TestConventional(t *testing.T) { ParsedMessage: "no scope", Tag: "feat", TagString: "Features", + Subject: "no scope", + MessageBlocks: map[string][]shared.MessageBlock{}, Print: true, }, }, @@ -77,6 +81,8 @@ func TestConventional(t *testing.T) { Tag: "feat", TagString: "Features", Print: true, + Subject: "my first commit", + MessageBlocks: map[string][]shared.MessageBlock{}, }, }, "major": { @@ -92,6 +98,9 @@ func TestConventional(t *testing.T) { TagString: "Features", Print: true, ParsedBreakingChangeMessage: "my first break", + IsBreaking: true, + Subject: "my first break", + MessageBlocks: map[string][]shared.MessageBlock{}, }, }, "patch": {}, @@ -125,6 +134,8 @@ func TestConventional(t *testing.T) { Tag: "feat", TagString: "Features", Print: true, + Subject: "my first commit", + MessageBlocks: map[string][]shared.MessageBlock{}, }, }, "major": { @@ -140,6 +151,15 @@ func TestConventional(t *testing.T) { TagString: "Features", Print: true, ParsedBreakingChangeMessage: "change api to v2", + IsBreaking: true, + Subject: "my first break", + MessageBlocks: map[string][]shared.MessageBlock{ + "body" : { shared.MessageBlock{ + Label: "BREAKING CHANGE", + Content: "change api to v2", + }, + }, + }, }, { Commit: shared.Commit{ @@ -153,6 +173,15 @@ func TestConventional(t *testing.T) { TagString: "Features", Print: true, ParsedBreakingChangeMessage: "hey from the change", + IsBreaking: true, + Subject: "my first break", + MessageBlocks: map[string][]shared.MessageBlock{ + "body" : {shared.MessageBlock{ + Label: "BREAKING CHANGE", + Content: "hey from the change", + }, + }, + }, }, }, "patch": {}, @@ -212,6 +241,8 @@ func TestConventional(t *testing.T) { Tag: "feat", TagString: "Features", Print: true, + Subject: "my first commit", + MessageBlocks: map[string][]shared.MessageBlock{}, }, }, "none": { @@ -227,6 +258,8 @@ func TestConventional(t *testing.T) { TagString: "Changes to CI/CD", Print: false, ParsedBreakingChangeMessage: "", + Subject: "my first build", + MessageBlocks: map[string][]shared.MessageBlock{}, }, }, "patch": {}, @@ -262,6 +295,8 @@ func TestConventional(t *testing.T) { TagString: "Changes to CI/CD", Print: false, ParsedBreakingChangeMessage: "", + Subject: "my first build", + MessageBlocks: map[string][]shared.MessageBlock{}, }, }, "patch": {{ @@ -275,6 +310,8 @@ func TestConventional(t *testing.T) { Tag: "fix", TagString: "Bug fixes", Print: true, + Subject: "my first commit", + MessageBlocks: map[string][]shared.MessageBlock{}, }}, "major": {}, }, @@ -291,9 +328,53 @@ func TestConventional(t *testing.T) { }, }, }, + { + testCase: "fix issue with footers", + wantAnalyzedCommits: map[shared.Release][]shared.AnalyzedCommit{ + "patch": {{ + Commit: shared.Commit{ + Message: "fix: squash bug for logging\n\nNote: now the logs will not print lines twice.\n\nIssue: #123\nSeverity: medium", + Author: "me", + Hash: "12345667", + }, + Scope: "", + ParsedMessage: "squash bug for logging\n\nNote: now the logs will not print lines twice.\n\nIssue: #123\nSeverity: medium", + Tag: "fix", + TagString: "Bug fixes", + Print: true, + Subject: "squash bug for logging", + MessageBlocks: map[string][]shared.MessageBlock{ + "body": { shared.MessageBlock{ + Label: "Note", + Content: "now the logs will not print lines twice.", + }, + }, + "footer": { shared.MessageBlock{ + Label: "Issue", + Content: "#123", + }, + shared.MessageBlock{ + Label: "Severity", + Content: "medium", + }, + }, + }, + }}, + "minor": {}, + "major": {}, + "none": {}, + }, + commits: []shared.Commit{ + { + Message: "fix: squash bug for logging\n\nNote: now the logs will not print lines twice.\n\nIssue: #123\nSeverity: medium", + Author: "me", + Hash: "12345667", + }, + }, + }, } - conventional, err := analyzer.New("conventional", config.ChangelogConfig{}) + conventional, err := analyzer.New("conventional", config.AnalyzerConfig{BlockPrefixes: []string{"Note", "Issue", "Severity"}}, config.ChangelogConfig{}) assert.NoError(t, err) for _, test := range testConfigs { diff --git a/internal/cache/cache_test.go b/internal/cache/cache_test.go index 4267836..225b5a7 100644 --- a/internal/cache/cache_test.go +++ b/internal/cache/cache_test.go @@ -69,6 +69,8 @@ func TestWriteAndReadCache(t *testing.T) { Tag: "feat", TagString: "Features", Print: true, + Subject: "add gitlab as release option", + MessageBlocks: map[string][]shared.MessageBlock{}, }, }, }, diff --git a/internal/changelog/changelog.go b/internal/changelog/changelog.go index a2698f0..7df00bc 100644 --- a/internal/changelog/changelog.go +++ b/internal/changelog/changelog.go @@ -110,7 +110,7 @@ func (c *Changelog) GenerateChanglog(templateConfig shared.ChangelogTemplateConf for _, commits := range analyzedCommits { for _, commit := range commits { if commit.Print { - if commit.ParsedBreakingChangeMessage != "" { + if commit.IsBreaking { commitsBreakingChange = append(commitsBreakingChange, commit) continue } @@ -142,6 +142,7 @@ func (c *Changelog) GenerateChanglog(templateConfig shared.ChangelogTemplateConf HasDockerLatest: c.config.Changelog.Docker.Latest, DockerRepository: c.config.Changelog.Docker.Repository, } + template := defaultCommitListSubTemplate + defaultChangelog if c.config.Changelog.TemplatePath != "" { content, err := ioutil.ReadFile(c.config.Changelog.TemplatePath) diff --git a/internal/changelog/changelog_test.go b/internal/changelog/changelog_test.go index 8ff146c..a5ad35c 100644 --- a/internal/changelog/changelog_test.go +++ b/internal/changelog/changelog_test.go @@ -41,6 +41,8 @@ func TestChangelog(t *testing.T) { Tag: "feat", TagString: "Features", Print: true, + Subject: "my first commit", + MessageBlocks: map[string][]shared.MessageBlock{}, }, }, }, @@ -64,6 +66,8 @@ func TestChangelog(t *testing.T) { Tag: "feat", TagString: "Features", Print: true, + Subject: "my first commit", + MessageBlocks: map[string][]shared.MessageBlock{}, }, }, }, @@ -88,6 +92,8 @@ func TestChangelog(t *testing.T) { Tag: "feat", TagString: "Features", Print: true, + Subject: "my first commit", + MessageBlocks: map[string][]shared.MessageBlock{}, }, { Commit: shared.Commit{ @@ -101,6 +107,15 @@ func TestChangelog(t *testing.T) { TagString: "Features", Print: true, ParsedBreakingChangeMessage: "change api to v2", + IsBreaking: true, + Subject: "my first break", + MessageBlocks: map[string][]shared.MessageBlock{ + "body" : { shared.MessageBlock{ + Label: "BREAKING CHANGE", + Content: "change api to v2", + }, + }, + }, }, }, }, @@ -126,6 +141,15 @@ func TestChangelog(t *testing.T) { TagString: "Features", Print: true, ParsedBreakingChangeMessage: "hey from the change", + IsBreaking: true, + Subject: "my first break", + MessageBlocks: map[string][]shared.MessageBlock{ + "body" : { shared.MessageBlock{ + Label: "BREAKING CHANGE", + Content: "hey from the change", + }, + }, + }, }, { Commit: shared.Commit{ @@ -138,6 +162,8 @@ func TestChangelog(t *testing.T) { Tag: "feat", TagString: "Features", Print: true, + Subject: "my first commit", + MessageBlocks: map[string][]shared.MessageBlock{}, }, { Commit: shared.Commit{ @@ -150,10 +176,12 @@ func TestChangelog(t *testing.T) { Tag: "feat", TagString: "Features", Print: true, + Subject: "my second commit", + MessageBlocks: map[string][]shared.MessageBlock{}, }, { Commit: shared.Commit{ - Message: "feat: my new commit \n\nmy first break: BREAKING CHANGE: change api to v2", + Message: "feat: my new commit \n\nBREAKING CHANGE: change api to v2", Author: "me", Hash: "12345668", }, @@ -163,6 +191,14 @@ func TestChangelog(t *testing.T) { TagString: "Features", Print: true, ParsedBreakingChangeMessage: "change api to v2", + IsBreaking: true, + Subject: "my new commit", + MessageBlocks: map[string][]shared.MessageBlock{ + "body": { shared.MessageBlock{ + Label: "BREAKING CHANGE", + Content: "change api to v2", + }}, + }, }, { Commit: shared.Commit{ @@ -176,6 +212,9 @@ func TestChangelog(t *testing.T) { TagString: "Features", Print: true, ParsedBreakingChangeMessage: "my next commit", + IsBreaking: true, + Subject: "my next commit", + MessageBlocks: map[string][]shared.MessageBlock{}, }, }, }, diff --git a/internal/shared/shared.go b/internal/shared/shared.go index 5aee964..4be867b 100644 --- a/internal/shared/shared.go +++ b/internal/shared/shared.go @@ -37,13 +37,22 @@ type ChangelogTemplateConfig struct { type AnalyzedCommit struct { Commit Commit `yaml:"commit"` ParsedMessage string `yaml:"parsedMessage"` - Scope Scope `yaml:"scope"` ParsedBreakingChangeMessage string `yaml:"parsedBreakingChangeMessage"` Tag string `yaml:"tag"` TagString string `yaml:"tagString"` + Scope Scope `yaml:"scope"` + Subject string `yaml:"subject"` + MessageBlocks map[string][]MessageBlock `yaml:"messageBlocks"` + IsBreaking bool `yaml:"isBreaking"` Print bool `yaml:"print"` } +// MessageBlock represents a block in the body section of a commit message +type MessageBlock struct { + Label string `yaml:"label""` + Content string `yaml:"content"` +} + //Scope of the commit, like feat, fix,.. type Scope string diff --git a/pkg/config/config.go b/pkg/config/config.go index 091a7ff..ba4266f 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -13,6 +13,11 @@ const ( DefaultTagPrefix = "v" ) +// AnalyzerConfig struct +type AnalyzerConfig struct { + BlockPrefixes []string `yaml:"blockPrefixes"` +} + // ChangelogConfig struct type ChangelogConfig struct { PrintAll bool `yaml:"printAll,omitempty"` @@ -83,6 +88,7 @@ type Checksum struct { type ReleaseConfig struct { CommitFormat string `yaml:"commitFormat"` Branch map[string]string `yaml:"branch"` + Analyzer AnalyzerConfig `yaml:"analyzer"` Changelog ChangelogConfig `yaml:"changelog,omitempty"` Release string `yaml:"release,omitempty"` GitHubProvider GitHubProvider `yaml:"github,omitempty"` diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 65bbc00..27cf14c 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -100,6 +100,7 @@ github: Compress: false}}, ReleaseTitle: "go-semantic-release release", IsPreRelease: false, + Analyzer: config.AnalyzerConfig{BlockPrefixes: []string{}}, }, result) } diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index eb1d67d..5eb174b 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -39,7 +39,7 @@ func New(c *config.ReleaseConfig, repository string, checkConfig bool) (*Semanti return nil, err } - analyzer, err := analyzer.New(c.CommitFormat, c.Changelog) + analyzer, err := analyzer.New(c.CommitFormat, c.Analyzer, c.Changelog) if err != nil { return nil, err }