From 637d8758ec0eaf9292cce3a2f8ba7cf3d2d83f6e Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 14 May 2019 19:36:31 +0200 Subject: [PATCH 01/77] build(travis): add travis.yml --- .travis.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..ddb2b68 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,27 @@ +dist: xenial + +language: go +go: + - 1.12.x + +services: +- docker + +notifications: + email: false + +git: + depth: 1 + +before_script: + - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.16.0 + +script: + - golangci-lint run + - go test -v ./... + - go build -o build/go-semantic-release ./cmd/go-semantic-release/ + - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe ./cmd/go-semantic-release/ + +branches: + except: + - /^v\d+\.\d+\.\d+$/ \ No newline at end of file From a2954759a0eed02fb0f1dd2f7fc5fc9bc4d02717 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 14 May 2019 19:40:36 +0200 Subject: [PATCH 02/77] build(travis): enable go mod --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index ddb2b68..94ecd57 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,9 @@ notifications: git: depth: 1 +env: + - GO111MODULE=on + before_script: - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.16.0 From 9aa7adedcead75b8312be08109e1dde387eecc42 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 14 May 2019 19:42:42 +0200 Subject: [PATCH 03/77] refactor(internal): remove empty file --- internal/sdk/sdk.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 internal/sdk/sdk.go diff --git a/internal/sdk/sdk.go b/internal/sdk/sdk.go deleted file mode 100644 index e69de29..0000000 From 20698c9679ee838d81da87c4883271fb6ea37180 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 14 May 2019 20:19:36 +0200 Subject: [PATCH 04/77] style(lint): fix lint issues --- .golangci.yml | 11 +++++++++++ .travis.yml | 2 +- cmd/go-semantic-release/main.go | 1 + internal/analyzer/analyzer.go | 20 ++++++++++++------- internal/analyzer/angular.go | 11 ++++++----- internal/gitutil/gitutil.go | 26 ++++++++++++++++--------- internal/storage/storage.go | 1 + pkg/semanticrelease/semantic-release.go | 21 ++++++++++++-------- 8 files changed, 63 insertions(+), 30 deletions(-) create mode 100644 .golangci.yml diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..0e24022 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,11 @@ +run: + tests: true + +linters-settings: + golint: + min-confidence: 0 +issues: + exclude-use-default: false +linters: + enable: + - golint \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 94ecd57..18bbec3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ before_script: - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.16.0 script: - - golangci-lint run + - golangci-lint run --golint.min-confidence 0 --exclude-use-default=no - go test -v ./... - go build -o build/go-semantic-release ./cmd/go-semantic-release/ - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe ./cmd/go-semantic-release/ diff --git a/cmd/go-semantic-release/main.go b/cmd/go-semantic-release/main.go index 73241e2..c81523a 100644 --- a/cmd/go-semantic-release/main.go +++ b/cmd/go-semantic-release/main.go @@ -1,3 +1,4 @@ +// Package main as start point for go build package main import ( diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go index 3e32c64..93b4578 100644 --- a/internal/analyzer/analyzer.go +++ b/internal/analyzer/analyzer.go @@ -1,3 +1,4 @@ +// Package analyzer provides different commit analyzer package analyzer import ( @@ -5,20 +6,23 @@ import ( log "github.com/sirupsen/logrus" ) +//Analyzer struct type Analyzer struct { CommitFormat string } +//Rules for commits type Rules struct { Tag string Release string } -type AnalyzeCommit interface { - Analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bool) - GetRules() []Rules +type analyzeCommit interface { + analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bool) + getRules() []Rules } +//AnalyzedCommit struct type AnalyzedCommit struct { Commit gitutil.Commit ParsedMessage string @@ -26,6 +30,7 @@ type AnalyzedCommit struct { ParsedBreakingChangeMessage string } +//New Analyzer struct for given commit format func New(format string) *Analyzer { return &Analyzer{ CommitFormat: format, @@ -33,13 +38,14 @@ func New(format string) *Analyzer { } +// Analyze commits and return commits splitted by major,minor,patch func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit { - var commitAnalayzer AnalyzeCommit + var commitAnalayzer analyzeCommit switch a.CommitFormat { case "angular": log.Infof("analyze angular format") - commitAnalayzer = NewAngular() + commitAnalayzer = newAngular() } analyzedCommits := make(map[string][]AnalyzedCommit) @@ -48,8 +54,8 @@ func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit analyzedCommits["patch"] = make([]AnalyzedCommit, 0) for _, commit := range commits { - for _, rule := range commitAnalayzer.GetRules() { - analyzedCommit, hasBreakingChange := commitAnalayzer.Analyze(commit, rule.Tag) + for _, rule := range commitAnalayzer.getRules() { + analyzedCommit, hasBreakingChange := commitAnalayzer.analyze(commit, rule.Tag) if hasBreakingChange { analyzedCommits["major"] = append(analyzedCommits["major"], analyzedCommit) } else { diff --git a/internal/analyzer/angular.go b/internal/analyzer/angular.go index 936e42e..178fc7e 100644 --- a/internal/analyzer/angular.go +++ b/internal/analyzer/angular.go @@ -1,3 +1,4 @@ +// Package analyzer provides different commit analyzer package analyzer import ( @@ -7,13 +8,13 @@ import ( "github.com/Nightapes/go-semantic-release/internal/gitutil" ) -type Angular struct { +type angular struct { rules []Rules regex string } -func NewAngular() *Angular { - return &Angular{ +func newAngular() *angular { + return &angular{ regex: `(TAG)(?:\((.*)\))?: (.*)`, rules: []Rules{ { @@ -31,11 +32,11 @@ func NewAngular() *Angular { } } -func (a *Angular) GetRules() []Rules { +func (a *angular) getRules() []Rules { return a.rules } -func (a *Angular) Analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bool) { +func (a *angular) analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bool) { analyzed := AnalyzedCommit{ Commit: commit, diff --git a/internal/gitutil/gitutil.go b/internal/gitutil/gitutil.go index f68f7eb..fff3b7b 100644 --- a/internal/gitutil/gitutil.go +++ b/internal/gitutil/gitutil.go @@ -1,3 +1,4 @@ +// Package gitutil provides helper methods for git package gitutil import ( @@ -10,29 +11,33 @@ import ( "gopkg.in/src-d/go-git.v4/plumbing/object" ) +// Commit struct type Commit struct { Message string Author string Hash string } -type GitUtils struct { +// GitUtil struct +type GitUtil struct { Repository *git.Repository } -func New(folder string) (*GitUtils, error) { +// New GitUtil struct and open git repository +func New(folder string) (*GitUtil, error) { r, err := git.PlainOpen(folder) if err != nil { return nil, err } - utils := &GitUtils{ + utils := &GitUtil{ Repository: r, } return utils, nil } -func (g *GitUtils) GetHash() (string, error) { +// GetHash from git HEAD +func (g *GitUtil) GetHash() (string, error) { ref, err := g.Repository.Head() if err != nil { return "", err @@ -40,20 +45,22 @@ func (g *GitUtils) GetHash() (string, error) { return ref.Hash().String(), nil } -func (g *GitUtils) GetBranch() (string, error) { +// GetBranch from git HEAD +func (g *GitUtil) GetBranch() (string, error) { ref, err := g.Repository.Head() if err != nil { return "", err } if !ref.Name().IsBranch() { - return "", fmt.Errorf("No branch found, found %s, please checkout a branch (git checkout )", ref.Name().String()) + return "", fmt.Errorf("no branch found, found %s, please checkout a branch (git checkout )", ref.Name().String()) } return ref.Name().Short(), nil } -func (g *GitUtils) GetLastVersion() (*semver.Version, string, error) { +// GetLastVersion from git tags +func (g *GitUtil) GetLastVersion() (*semver.Version, string, error) { log.Debugf("GetLastVersion") @@ -103,7 +110,8 @@ func (g *GitUtils) GetLastVersion() (*semver.Version, string, error) { return tags[0], tagObject.Target.String(), nil } -func (g *GitUtils) GetCommits(lastTagHash string) ([]Commit, error) { +// GetCommits from git hash to HEAD +func (g *GitUtil) GetCommits(lastTagHash string) ([]Commit, error) { log.Printf("Read head") ref, err := g.Repository.Head() @@ -136,5 +144,5 @@ func (g *GitUtils) GetCommits(lastTagHash string) ([]Commit, error) { return nil }) - return commits, nil + return commits, err } diff --git a/internal/storage/storage.go b/internal/storage/storage.go index 76787cc..fc2bb91 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -1,3 +1,4 @@ +// Package storage helper for saving/reading version file package storage import ( diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index 5d97007..291d5db 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -1,3 +1,4 @@ +// Package semanticrelease provides public methods to include in own code package semanticrelease import ( @@ -10,7 +11,7 @@ import ( log "github.com/sirupsen/logrus" ) -// GetNextVersion from .version or calculate new +// GetNextVersion from .version or calculate new from commits func GetNextVersion(repro string) error { util, err := gitutil.New(repro) if err != nil { @@ -38,8 +39,11 @@ func GetNextVersion(repro string) error { if lastVersion == nil { defaultVersion, _ := semver.NewVersion("1.0.0") - SetVersion(defaultVersion.String(), repro) - fmt.Printf(defaultVersion.String()) + err := SetVersion(defaultVersion.String(), repro) + if err != nil { + return err + } + fmt.Printf("%s", defaultVersion.String()) return nil } @@ -64,12 +68,16 @@ func GetNextVersion(repro string) error { newVersion = lastVersion.IncPatch() } - SetVersion(newVersion.String(), repro) - fmt.Printf(newVersion.String()) + err = SetVersion(newVersion.String(), repro) + if err != nil { + return err + } + fmt.Printf("%s", newVersion.String()) return err } +//SetVersion for git repository func SetVersion(version string, repro string) error { util, err := gitutil.New(repro) @@ -109,6 +117,3 @@ func SetVersion(version string, repro string) error { return storage.Write(newVersionContent) } - -func Release() { -} From 1dee6e98729f026c2cff9bd49d2762a7f77cb11c Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 14 May 2019 20:22:23 +0200 Subject: [PATCH 05/77] build(travis): update golangci-lint run call --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 18bbec3..a6a973d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ before_script: - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.16.0 script: - - golangci-lint run --golint.min-confidence 0 --exclude-use-default=no + - golangci-lint run ./... - go test -v ./... - go build -o build/go-semantic-release ./cmd/go-semantic-release/ - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe ./cmd/go-semantic-release/ From d0c018a5b8c36b15cc16ea70567354b72d92417e Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 14 May 2019 20:25:05 +0200 Subject: [PATCH 06/77] build(travis): enable cache --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index a6a973d..d078e60 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,11 @@ language: go go: - 1.12.x +cache: + directories: + - $HOME/.cache/go-build + - $HOME/gopath/pkg/mod + services: - docker From abede95350a7be5278919110ed359f1df47bbfb5 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 14 May 2019 21:39:39 +0200 Subject: [PATCH 07/77] refactor(cli): clean up comands --- cmd/go-semantic-release/main.go | 115 ++++++++------------------------ go.mod | 7 +- go.sum | 19 +++--- 3 files changed, 42 insertions(+), 99 deletions(-) diff --git a/cmd/go-semantic-release/main.go b/cmd/go-semantic-release/main.go index c81523a..0ff68c5 100644 --- a/cmd/go-semantic-release/main.go +++ b/cmd/go-semantic-release/main.go @@ -6,100 +6,39 @@ import ( "github.com/Nightapes/go-semantic-release/pkg/semanticrelease" log "github.com/sirupsen/logrus" - "gopkg.in/urfave/cli.v1" // imports as package "cli" + "gopkg.in/alecthomas/kingpin.v2" +) + +var ( + app = kingpin.New("go-semantic-release", "A command-line for releasing software") + loglevel = app.Flag("loglevel", "Set loglevel.").Default("error").HintOptions("error", "warning", "info", "debug").Short('l').String() + + nextCommand = app.Command("next", "Print next version") + nextRepository = nextCommand.Flag("repository", "Path to repository").String() + + setCommand = app.Command("set", "Set version for current build.") + setRepository = setCommand.Flag("repository", "Path to repository").String() + setVersion = setCommand.Arg("version", "semver version").Required().String() ) func main() { - app := cli.NewApp() + switch kingpin.MustParse(app.Parse(os.Args[1:])) { + case nextCommand.FullCommand(): + setLoglevel(*loglevel) + err := semanticrelease.GetNextVersion(*nextRepository) + if err != nil { + log.Fatal(err) + } - app.Flags = []cli.Flag{ - cli.StringFlag{ - Name: "loglevel", - Value: "error", - Usage: "Set loglevel 'LEVEL", - }, + case setCommand.FullCommand(): + setLoglevel(*loglevel) + log.Infof("Version %s", *setVersion) + err := semanticrelease.SetVersion(*setVersion, *setRepository) + if err != nil { + log.Fatal(err) + } } - app.Commands = []cli.Command{ - { - Name: "version", - Aliases: []string{"v"}, - Usage: "version commands", - Subcommands: []cli.Command{ - { - Name: "set", - Usage: "set version `VERSION`", - Action: func(c *cli.Context) error { - setLoglevel(c.GlobalString("loglevel")) - path := c.String("path") - version := c.Args().First() - log.Infof("Version %s", version) - return semanticrelease.SetVersion(version, path) - }, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Value: "release-config.json", - Usage: "Load release configuration from `FILE`", - }, - cli.StringFlag{ - Name: "path, p", - Usage: "`PATH` to repro ", - }, - }, - }, - { - Name: "next", - Usage: "get next `VERSION` or the set one ", - Action: func(c *cli.Context) error { - setLoglevel(c.GlobalString("loglevel")) - path := c.String("path") - return semanticrelease.GetNextVersion(path) - }, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Value: "release-config.json", - Usage: "Load release configuration from `FILE`", - }, - cli.StringFlag{ - Name: "path, p", - Usage: "`PATH` to repro ", - }, - }, - }, - }, - }, - { - Name: "release", - Aliases: []string{}, - Usage: "make release", - Action: func(c *cli.Context) error { - return nil - }, - Flags: []cli.Flag{ - cli.StringFlag{ - Name: "config, c", - Value: "release-config.json", - Usage: "Load release configuration from `FILE`", - }, - }, - }, - { - Name: "init", - Aliases: []string{}, - Usage: "create config", - Action: func(c *cli.Context) error { - return nil - }, - }, - } - - //gitutil.GetCommits(folder) - err := app.Run(os.Args) - if err != nil { - log.Fatal(err) - } } func setLoglevel(level string) { diff --git a/go.mod b/go.mod index 738c147..89ee791 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,11 @@ go 1.12 require ( github.com/Masterminds/semver v1.4.2 + github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect + github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect github.com/sirupsen/logrus v1.4.1 - github.com/urfave/cli v1.20.0 // indirect - golang.org/x/tools v0.0.0-20190508150211-cf84161cff3f // indirect + golang.org/x/net v0.0.0-20190311183353-d8887717615a // indirect + gopkg.in/alecthomas/kingpin.v2 v2.2.6 gopkg.in/src-d/go-git.v4 v4.11.0 - gopkg.in/urfave/cli.v1 v1.20.0 gopkg.in/yaml.v2 v2.2.2 ) diff --git a/go.sum b/go.sum index e4a93b0..1561e63 100644 --- a/go.sum +++ b/go.sum @@ -2,13 +2,21 @@ github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITg github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emirpasic/gods v1.9.0 h1:rUF4PuzEjMChMiNsVjdI+SyLu7rEqpQ5reNFnhC7oFo= github.com/emirpasic/gods v1.9.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= @@ -26,6 +34,7 @@ github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnG github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA= github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= +github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -38,8 +47,6 @@ github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jW github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/xanzy/ssh-agent v0.2.0 h1:Adglfbi5p9Z0BmK2oKU9nTG+zKfniSfnaMYB+ULd+Ro= github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I= @@ -50,8 +57,6 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9 h1:lkiLiLBHGoH3XnqSLUIaBsilGMUjI+Uy2Xu2JLUtTas= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -59,8 +64,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190508150211-cf84161cff3f h1:sjxqKRXfnzgJFg/igBXeLZoBVAKXuAAljgr+PcNr7u8= -golang.org/x/tools v0.0.0-20190508150211-cf84161cff3f/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -70,8 +75,6 @@ gopkg.in/src-d/go-git-fixtures.v3 v3.1.1 h1:XWW/s5W18RaJpmo1l0IYGqXKuJITWRFuA45i gopkg.in/src-d/go-git-fixtures.v3 v3.1.1/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= gopkg.in/src-d/go-git.v4 v4.11.0 h1:cJwWgJ0DXifrNrXM6RGN1Y2yR60Rr1zQ9Q5DX5S9qgU= gopkg.in/src-d/go-git.v4 v4.11.0/go.mod h1:Vtut8izDyrM8BUVQnzJ+YvmNcem2J89EmfZYCkLokZk= -gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= From 3c3ba8dacb2d431fe8f22a5ba32ccf8cf96070cc Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Tue, 14 May 2019 22:20:23 +0200 Subject: [PATCH 08/77] chore(.gitignore): add 'go-semantic-release' binary for development on linux --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d63d50d..ad23d73 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.dll *.so *.dylib +go-semantic-release # Test binary, build with `go test -c` *.test From d7664eb8e8b6567d289bc416b9575369ce75ea12 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Wed, 15 May 2019 22:09:52 +0200 Subject: [PATCH 09/77] feat(config): add config file --- .release.yml | 15 +++ cmd/go-semantic-release/main.go | 20 +++- internal/analyzer/analyzer.go | 1 + internal/analyzer/angular.go | 3 + .../{storage/storage.go => cache/cache.go} | 4 +- pkg/config/config.go | 55 +++++++++++ pkg/semanticrelease/semantic-release.go | 91 +++++++++++++++---- 7 files changed, 165 insertions(+), 24 deletions(-) create mode 100644 .release.yml rename internal/{storage/storage.go => cache/cache.go} (91%) create mode 100644 pkg/config/config.go diff --git a/.release.yml b/.release.yml new file mode 100644 index 0000000..8c95ab9 --- /dev/null +++ b/.release.yml @@ -0,0 +1,15 @@ +commitFormat: angular +branch: + master: release + travis: rc + beta: beta + alpha: alpha +changelog: + print: all/compact + template: '' + templatePath: '' +release: 'github' +github: + url: '' +gitlab: + url: '' diff --git a/cmd/go-semantic-release/main.go b/cmd/go-semantic-release/main.go index 0ff68c5..7bf2848 100644 --- a/cmd/go-semantic-release/main.go +++ b/cmd/go-semantic-release/main.go @@ -4,7 +4,9 @@ package main import ( "os" + "github.com/Nightapes/go-semantic-release/pkg/config" "github.com/Nightapes/go-semantic-release/pkg/semanticrelease" + log "github.com/sirupsen/logrus" "gopkg.in/alecthomas/kingpin.v2" ) @@ -15,17 +17,22 @@ var ( nextCommand = app.Command("next", "Print next version") nextRepository = nextCommand.Flag("repository", "Path to repository").String() + nextConfigPath = nextCommand.Flag("config", "Path to config file").Default(".release.yml").String() + nextForce = nextCommand.Flag("force", "Ignore cache, don't use in ci build").Bool() setCommand = app.Command("set", "Set version for current build.") setRepository = setCommand.Flag("repository", "Path to repository").String() + setConfigPath = setCommand.Flag("config", "Path to config file").Default(".release.yml").String() setVersion = setCommand.Arg("version", "semver version").Required().String() ) func main() { + switch kingpin.MustParse(app.Parse(os.Args[1:])) { case nextCommand.FullCommand(): setLoglevel(*loglevel) - err := semanticrelease.GetNextVersion(*nextRepository) + s := semanticrelease.New(readConfig(nextConfigPath)) + err := s.GetNextVersion(*nextRepository, *nextForce) if err != nil { log.Fatal(err) } @@ -33,7 +40,8 @@ func main() { case setCommand.FullCommand(): setLoglevel(*loglevel) log.Infof("Version %s", *setVersion) - err := semanticrelease.SetVersion(*setVersion, *setRepository) + s := semanticrelease.New(readConfig(setConfigPath)) + err := s.SetVersion(*setVersion, *setRepository) if err != nil { log.Fatal(err) } @@ -41,6 +49,14 @@ func main() { } +func readConfig(path *string) *config.ReleaseConfig { + releaseConfig, err := config.Read(*path) + if err != nil { + log.Fatal(err) + } + return releaseConfig +} + func setLoglevel(level string) { parsed, err := log.ParseLevel(level) if err != nil { diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go index 93b4578..7ab0abd 100644 --- a/internal/analyzer/analyzer.go +++ b/internal/analyzer/analyzer.go @@ -15,6 +15,7 @@ type Analyzer struct { type Rules struct { Tag string Release string + Enabled bool } type analyzeCommit interface { diff --git a/internal/analyzer/angular.go b/internal/analyzer/angular.go index 178fc7e..4db7cf4 100644 --- a/internal/analyzer/angular.go +++ b/internal/analyzer/angular.go @@ -20,13 +20,16 @@ func newAngular() *angular { { Tag: "feat", Release: "minor", + Enabled: true, }, { Tag: "fix", Release: "patch", + Enabled: true, }, { Tag: "perf", Release: "patch", + Enabled: true, }, }, } diff --git a/internal/storage/storage.go b/internal/cache/cache.go similarity index 91% rename from internal/storage/storage.go rename to internal/cache/cache.go index fc2bb91..e64a061 100644 --- a/internal/storage/storage.go +++ b/internal/cache/cache.go @@ -1,5 +1,5 @@ -// Package storage helper for saving/reading version file -package storage +// Package cache helper for cache version +package cache import ( "io/ioutil" diff --git a/pkg/config/config.go b/pkg/config/config.go new file mode 100644 index 0000000..2ad014c --- /dev/null +++ b/pkg/config/config.go @@ -0,0 +1,55 @@ +// Package config provides defimition of .release.yml and read method +package config + +import ( + "io/ioutil" + + log "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" +) + +// ChangelogConfig struct +type ChangelogConfig struct { + Print string `yaml:"print,omitempty"` + Template string `yaml:"template,omitempty"` + TemplatePath string `yaml:"templatePath,omitempty"` +} + +// GithubConfig struct +type GithubConfig struct { + URL string `yaml:"url"` +} + +// GitlabConfig struct +type GitlabConfig struct { + URL string `yaml:"url"` +} + +// ReleaseConfig struct +type ReleaseConfig struct { + CommitFormat string `yaml:"commitFormat"` + Branch map[string]string `yaml:"branch"` + Changelog ChangelogConfig `yaml:"changelog,omitempty"` + Release string `yaml:"release,omitempty"` + Github map[string]string `yaml:"github"` + Gitlab map[string]string `yaml:"gitlab"` +} + +// Read ReleaseConfig +func Read(configPath string) (*ReleaseConfig, error) { + + content, err := ioutil.ReadFile(configPath) + if err != nil { + return &ReleaseConfig{}, err + } + + var releaseConfig ReleaseConfig + err = yaml.Unmarshal(content, &releaseConfig) + if err != nil { + return &ReleaseConfig{}, err + } + + log.Debugf("Found config %+v", releaseConfig) + + return &releaseConfig, nil +} diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index 291d5db..c41f567 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -3,16 +3,31 @@ package semanticrelease import ( "fmt" + "strconv" + "strings" "github.com/Masterminds/semver" "github.com/Nightapes/go-semantic-release/internal/analyzer" + "github.com/Nightapes/go-semantic-release/internal/cache" "github.com/Nightapes/go-semantic-release/internal/gitutil" - "github.com/Nightapes/go-semantic-release/internal/storage" + "github.com/Nightapes/go-semantic-release/pkg/config" log "github.com/sirupsen/logrus" ) +// SemanticRelease struct +type SemanticRelease struct { + config *config.ReleaseConfig +} + +// New SemanticRelease struct +func New(c *config.ReleaseConfig) *SemanticRelease { + return &SemanticRelease{ + config: c, + } +} + // GetNextVersion from .version or calculate new from commits -func GetNextVersion(repro string) error { +func (s *SemanticRelease) GetNextVersion(repro string, force bool) error { util, err := gitutil.New(repro) if err != nil { return err @@ -23,15 +38,17 @@ func GetNextVersion(repro string) error { return err } - content, err := storage.Read() + log.Debugf("Ignore .version file if exits, %t", force) + if !force { + content, err := cache.Read() - if err == nil && content.Commit == hash { - fmt.Printf(content.NextVersion) - return nil + if err == nil && content.Commit == hash { + fmt.Printf(content.NextVersion) + return nil + } + 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() if err != nil { return err @@ -39,7 +56,7 @@ func GetNextVersion(repro string) error { if lastVersion == nil { defaultVersion, _ := semver.NewVersion("1.0.0") - err := SetVersion(defaultVersion.String(), repro) + err := s.SetVersion(defaultVersion.String(), repro) if err != nil { return err } @@ -59,16 +76,50 @@ func GetNextVersion(repro string) error { var newVersion semver.Version - if len(result["major"]) > 0 { - newVersion = lastVersion.IncMajor() - return nil - } else if len(result["minor"]) > 0 { - newVersion = lastVersion.IncMinor() - } else if len(result["patch"]) > 0 { - newVersion = lastVersion.IncPatch() + currentBranch, err := util.GetBranch() + if err != nil { + 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() + } } - err = SetVersion(newVersion.String(), repro) + log.Debugf("Test %+v", s.config) + for branch, releaseType := range s.config.Branch { + if currentBranch == branch || strings.HasPrefix(currentBranch, branch) { + log.Debugf("Found branch config for branch %s with release type %s", currentBranch, releaseType) + switch releaseType { + case "rc": + if newVersion.Prerelease() == "" || !strings.HasPrefix(newVersion.Prerelease(), "rc") { + newVersion, _ = newVersion.SetPrerelease("rc.0") + } else { + parts := strings.Split(newVersion.Prerelease(), ".") + if len(parts) == 2 { + i, err := strconv.Atoi(parts[1]) + if err != nil { + newVersion, _ = newVersion.SetPrerelease("rc.0") + 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()) + } + } + } + + } + } + + err = s.SetVersion(newVersion.String(), repro) if err != nil { return err } @@ -78,7 +129,7 @@ func GetNextVersion(repro string) error { } //SetVersion for git repository -func SetVersion(version string, repro string) error { +func (s *SemanticRelease) SetVersion(version string, repro string) error { util, err := gitutil.New(repro) if err != nil { @@ -100,7 +151,7 @@ func SetVersion(version string, repro string) error { return err } - newVersionContent := storage.VersionFileContent{ + newVersionContent := cache.VersionFileContent{ Commit: hash, NextVersion: newVersion.String(), Branch: branch, @@ -115,5 +166,5 @@ func SetVersion(version string, repro string) error { newVersionContent.Version = lastVersion.String() } - return storage.Write(newVersionContent) + return cache.Write(newVersionContent) } From 9f7d3e3b5833a64f42f92b3b2f93cd701d1f24ee Mon Sep 17 00:00:00 2001 From: Nightapes Date: Thu, 16 May 2019 21:30:35 +0200 Subject: [PATCH 10/77] refactor(versioning): clean up version calculation and logs --- .release.yml | 6 +- README2.md | 2 + internal/analyzer/analyzer.go | 27 ++++--- internal/analyzer/angular.go | 60 ++++++++++++---- internal/gitutil/gitutil.go | 30 ++++---- pkg/semanticrelease/semantic-release.go | 95 +++++++++++++------------ 6 files changed, 136 insertions(+), 84 deletions(-) create mode 100644 README2.md diff --git a/.release.yml b/.release.yml index 8c95ab9..3a1f903 100644 --- a/.release.yml +++ b/.release.yml @@ -1,9 +1,9 @@ commitFormat: angular branch: master: release - travis: rc - beta: beta - alpha: alpha + sd: rc + sds: beta + travis: alpha changelog: print: all/compact template: '' diff --git a/README2.md b/README2.md new file mode 100644 index 0000000..e68c535 --- /dev/null +++ b/README2.md @@ -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/ \ No newline at end of file diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go index 7ab0abd..541dd55 100644 --- a/internal/analyzer/analyzer.go +++ b/internal/analyzer/analyzer.go @@ -13,13 +13,13 @@ type Analyzer struct { //Rules for commits type Rules struct { - Tag string - Release string - Enabled bool + Tag string + Release string + Changelog bool } type analyzeCommit interface { - analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bool) + analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bool, error) getRules() []Rules } @@ -29,6 +29,7 @@ type AnalyzedCommit struct { ParsedMessage string Scope string ParsedBreakingChangeMessage string + Tag string } //New Analyzer struct for given commit format @@ -45,7 +46,7 @@ func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit var commitAnalayzer analyzeCommit switch a.CommitFormat { case "angular": - log.Infof("analyze angular format") + log.Debugf("Commit format set to angular") commitAnalayzer = newAngular() } @@ -53,18 +54,24 @@ func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit analyzedCommits["major"] = make([]AnalyzedCommit, 0) analyzedCommits["minor"] = make([]AnalyzedCommit, 0) analyzedCommits["patch"] = make([]AnalyzedCommit, 0) + analyzedCommits["none"] = make([]AnalyzedCommit, 0) for _, commit := range commits { for _, rule := range commitAnalayzer.getRules() { - analyzedCommit, hasBreakingChange := commitAnalayzer.analyze(commit, rule.Tag) - if hasBreakingChange { - analyzedCommits["major"] = append(analyzedCommits["major"], analyzedCommit) - } else { - analyzedCommits[rule.Release] = append(analyzedCommits[rule.Release], analyzedCommit) + analyzedCommit, hasBreakingChange, err := commitAnalayzer.analyze(commit, rule.Tag) + if err == nil { + if hasBreakingChange { + analyzedCommits["major"] = append(analyzedCommits["major"], analyzedCommit) + } else { + 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 } diff --git a/internal/analyzer/angular.go b/internal/analyzer/angular.go index 4db7cf4..b73354a 100644 --- a/internal/analyzer/angular.go +++ b/internal/analyzer/angular.go @@ -2,9 +2,12 @@ package analyzer import ( + "fmt" "regexp" "strings" + log "github.com/sirupsen/logrus" + "github.com/Nightapes/go-semantic-release/internal/gitutil" ) @@ -18,18 +21,43 @@ func newAngular() *angular { regex: `(TAG)(?:\((.*)\))?: (.*)`, rules: []Rules{ { - Tag: "feat", - Release: "minor", - Enabled: true, + Tag: "feat", + Release: "minor", + Changelog: true, }, { - Tag: "fix", - Release: "patch", - Enabled: true, + Tag: "fix", + Release: "patch", + Changelog: true, }, { - Tag: "perf", - Release: "patch", - Enabled: true, + Tag: "perf", + Release: "patch", + Changelog: true, + }, { + Tag: "docs", + Release: "none", + Changelog: false, + }, + { + Tag: "style", + Release: "none", + Changelog: false, + }, { + Tag: "refactor", + Release: "none", + Changelog: false, + }, { + Tag: "test", + Release: "none", + Changelog: false, + }, { + Tag: "chore", + Release: "none", + Changelog: false, + }, { + Tag: "build", + Release: "none", + Changelog: false, }, }, } @@ -39,14 +67,15 @@ func (a *angular) getRules() []Rules { return a.rules } -func (a *angular) analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bool) { +func (a *angular) analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bool, error) { analyzed := AnalyzedCommit{ Commit: commit, + Tag: tag, } re := regexp.MustCompile(strings.Replace(a.regex, "TAG", tag, -1)) - matches := re.FindAllStringSubmatch(commit.Message+" "+commit.Message, -1) + matches := re.FindAllStringSubmatch(commit.Message, -1) if len(matches) >= 1 { if len(matches[0]) >= 3 { analyzed.Scope = matches[0][2] @@ -56,14 +85,17 @@ func (a *angular) analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bo if len(splitted) == 1 { analyzed.ParsedMessage = splitted[0] - return analyzed, false + log.Tracef("%s: found %s", commit.Message, tag) + return analyzed, false, nil } analyzed.ParsedMessage = splitted[0] 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, tag) + return analyzed, false, fmt.Errorf("Not found") } diff --git a/internal/gitutil/gitutil.go b/internal/gitutil/gitutil.go index fff3b7b..028d35a 100644 --- a/internal/gitutil/gitutil.go +++ b/internal/gitutil/gitutil.go @@ -8,6 +8,7 @@ import ( "github.com/Masterminds/semver" log "github.com/sirupsen/logrus" "gopkg.in/src-d/go-git.v4" + "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/object" ) @@ -62,23 +63,27 @@ func (g *GitUtil) GetBranch() (string, error) { // GetLastVersion from git tags 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 { return nil, "", err } - var tags []*semver.Version - - err = tagObjects.ForEach(func(t *object.Tag) error { - v, err := semver.NewVersion(t.Name) - - if err != nil { - log.Debugf("Tag %s is not a valid version, skip", t.Name) + err = gitTags.ForEach(func(p *plumbing.Reference) error { + v, err := semver.NewVersion(p.Name().Short()) + log.Tracef("%+v", p.Name().Short()) + if err == nil { + _, err := g.Repository.TagObject(p.Hash()) + if err == nil { + log.Debugf("Add tag %s", p.Name().Short()) + tags = append(tags, v) + } else { + log.Debugf("Found tag %s, but is not annotated, skip", err.Error()) + } } else { - log.Debugf("Add tag %s", t.Name) - tags = append(tags, v) + log.Debugf("Tag %s is not a valid version, skip", p.Name().Short()) } return nil }) @@ -113,7 +118,6 @@ func (g *GitUtil) GetLastVersion() (*semver.Version, string, error) { // GetCommits from git hash to HEAD func (g *GitUtil) GetCommits(lastTagHash string) ([]Commit, error) { - log.Printf("Read head") ref, err := g.Repository.Head() if err != nil { return nil, err @@ -129,7 +133,7 @@ func (g *GitUtil) GetCommits(lastTagHash string) ([]Commit, error) { err = cIter.ForEach(func(c *object.Commit) error { 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 } diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index c41f567..94b1de2 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -43,6 +43,7 @@ func (s *SemanticRelease) GetNextVersion(repro string, force bool) error { content, err := cache.Read() if err == nil && content.Commit == hash { + log.Infof("Found cache, will return cached version %s", content.NextVersion) fmt.Printf(content.NextVersion) return nil } @@ -53,15 +54,13 @@ func (s *SemanticRelease) GetNextVersion(repro string, force bool) error { if err != nil { return err } + var newVersion semver.Version if lastVersion == nil { defaultVersion, _ := semver.NewVersion("1.0.0") - err := s.SetVersion(defaultVersion.String(), repro) - if err != nil { - return err - } - fmt.Printf("%s", defaultVersion.String()) - return nil + newVersion = *defaultVersion + } else { + newVersion = *lastVersion } commits, err := util.GetCommits(lastVersionHash) @@ -74,52 +73,31 @@ func (s *SemanticRelease) GetNextVersion(repro string, force bool) error { a := analyzer.New("angular") result := a.Analyze(commits) - var newVersion semver.Version - currentBranch, err := util.GetBranch() if err != nil { 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 { if currentBranch == branch || strings.HasPrefix(currentBranch, branch) { log.Debugf("Found branch config for branch %s with release type %s", currentBranch, releaseType) switch releaseType { - case "rc": - if newVersion.Prerelease() == "" || !strings.HasPrefix(newVersion.Prerelease(), "rc") { - newVersion, _ = newVersion.SetPrerelease("rc.0") - } else { - parts := strings.Split(newVersion.Prerelease(), ".") - if len(parts) == 2 { - i, err := strconv.Atoi(parts[1]) - if err != nil { - newVersion, _ = newVersion.SetPrerelease("rc.0") - 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()) - } + case "rc", "beta", "alpha": + newVersion = incPrerelease(releaseType, newVersion) + case "release": + if len(result["major"]) > 0 { + newVersion = newVersion.IncMajor() + } else if len(result["minor"]) > 0 { + newVersion = newVersion.IncMinor() + } else if len(result["patch"]) > 0 { + newVersion = newVersion.IncPatch() } } - } } - err = s.SetVersion(newVersion.String(), repro) + log.Infof("New version %s -> %s", lastVersion.String(), newVersion.String()) + err = saveToCache(util, lastVersion, &newVersion) if err != nil { return err } @@ -141,6 +119,16 @@ func (s *SemanticRelease) SetVersion(version string, repro string) error { 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() if err != nil { return err @@ -153,18 +141,37 @@ func (s *SemanticRelease) SetVersion(version string, repro string) error { newVersionContent := cache.VersionFileContent{ Commit: hash, - NextVersion: newVersion.String(), + NextVersion: nextVersion.String(), Branch: branch, } - lastVersion, _, err := util.GetLastVersion() - if err != nil { - return err - } - if lastVersion != nil { newVersionContent.Version = lastVersion.String() } + log.Debugf("Save %s with hash %s to cache", nextVersion.String(), hash) 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 +} From fc7e6366c2884ccdfd84eb0690f75e7fa0976fca Mon Sep 17 00:00:00 2001 From: Nightapes Date: Sat, 25 May 2019 18:10:24 +0200 Subject: [PATCH 11/77] feat(changelog): add first draft for changelog generation --- .release.yml | 8 +-- cmd/go-semantic-release/main.go | 16 ++++- internal/analyzer/analyzer.go | 23 +++++-- internal/analyzer/angular.go | 29 ++++++--- internal/changelog/changelog.go | 82 +++++++++++++++++++++++++ pkg/config/config.go | 2 +- pkg/semanticrelease/semantic-release.go | 62 +++++++++++++++---- 7 files changed, 188 insertions(+), 34 deletions(-) create mode 100644 internal/changelog/changelog.go diff --git a/.release.yml b/.release.yml index 3a1f903..730a27a 100644 --- a/.release.yml +++ b/.release.yml @@ -1,11 +1,11 @@ commitFormat: angular branch: master: release - sd: rc - sds: beta - travis: alpha + rc: rc + beta: beta + alpha: alpha changelog: - print: all/compact + printAll: false template: '' templatePath: '' release: 'github' diff --git a/cmd/go-semantic-release/main.go b/cmd/go-semantic-release/main.go index 7bf2848..d7cfd3a 100644 --- a/cmd/go-semantic-release/main.go +++ b/cmd/go-semantic-release/main.go @@ -2,6 +2,7 @@ package main import ( + "fmt" "os" "github.com/Nightapes/go-semantic-release/pkg/config" @@ -24,6 +25,11 @@ var ( setRepository = setCommand.Flag("repository", "Path to repository").String() setConfigPath = setCommand.Flag("config", "Path to config file").Default(".release.yml").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() { @@ -32,10 +38,11 @@ func main() { case nextCommand.FullCommand(): setLoglevel(*loglevel) s := semanticrelease.New(readConfig(nextConfigPath)) - err := s.GetNextVersion(*nextRepository, *nextForce) + version, err := s.GetNextVersion(*nextRepository, *nextForce) if err != nil { log.Fatal(err) } + fmt.Println(version) case setCommand.FullCommand(): setLoglevel(*loglevel) @@ -45,6 +52,13 @@ func main() { if err != nil { log.Fatal(err) } + case getChangelog.FullCommand(): + setLoglevel(*loglevel) + s := semanticrelease.New(readConfig(getChangelogConfigPath)) + err := s.GetChangelog(*getChangelogRepository, *getChangelogFile) + if err != nil { + log.Fatal(err) + } } } diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go index 541dd55..10f2cc3 100644 --- a/internal/analyzer/analyzer.go +++ b/internal/analyzer/analyzer.go @@ -3,24 +3,27 @@ package analyzer import ( "github.com/Nightapes/go-semantic-release/internal/gitutil" + "github.com/Nightapes/go-semantic-release/pkg/config" log "github.com/sirupsen/logrus" ) //Analyzer struct type Analyzer struct { CommitFormat string + Config config.ChangelogConfig } -//Rules for commits -type Rules struct { +//Rule for commits +type Rule struct { Tag string + TagString string Release string Changelog bool } type analyzeCommit interface { - analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bool, error) - getRules() []Rules + analyze(commit gitutil.Commit, tag Rule) (AnalyzedCommit, bool, error) + getRules() []Rule } //AnalyzedCommit struct @@ -30,12 +33,15 @@ type AnalyzedCommit struct { Scope string ParsedBreakingChangeMessage string Tag string + TagString string + Print bool } //New Analyzer struct for given commit format -func New(format string) *Analyzer { +func New(format string, config config.ChangelogConfig) *Analyzer { return &Analyzer{ CommitFormat: format, + Config: config, } } @@ -58,8 +64,13 @@ func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit for _, commit := range commits { for _, rule := range commitAnalayzer.getRules() { - analyzedCommit, hasBreakingChange, err := 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 { analyzedCommits["major"] = append(analyzedCommits["major"], analyzedCommit) } else { diff --git a/internal/analyzer/angular.go b/internal/analyzer/angular.go index b73354a..41e09c0 100644 --- a/internal/analyzer/angular.go +++ b/internal/analyzer/angular.go @@ -12,50 +12,59 @@ import ( ) type angular struct { - rules []Rules + rules []Rule regex string } func newAngular() *angular { return &angular{ regex: `(TAG)(?:\((.*)\))?: (.*)`, - rules: []Rules{ + rules: []Rule{ { Tag: "feat", + TagString: "Features", Release: "minor", Changelog: true, }, { Tag: "fix", + TagString: "Bug fixes", Release: "patch", Changelog: true, }, { Tag: "perf", + TagString: "Performance improvments", Release: "patch", 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, }, @@ -63,21 +72,23 @@ func newAngular() *angular { } } -func (a *angular) getRules() []Rules { +func (a *angular) getRules() []Rule { return a.rules } -func (a *angular) analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bool, error) { +func (a *angular) analyze(commit gitutil.Commit, rule Rule) (AnalyzedCommit, bool, error) { analyzed := AnalyzedCommit{ - Commit: commit, - Tag: tag, + 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, -1) if len(matches) >= 1 { if len(matches[0]) >= 3 { + analyzed.Scope = matches[0][2] message := strings.Join(matches[0][3:], "") @@ -85,7 +96,7 @@ func (a *angular) analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bo if len(splitted) == 1 { analyzed.ParsedMessage = splitted[0] - log.Tracef("%s: found %s", commit.Message, tag) + log.Tracef("%s: found %s", commit.Message, rule.Tag) return analyzed, false, nil } analyzed.ParsedMessage = splitted[0] @@ -95,7 +106,7 @@ func (a *angular) analyze(commit gitutil.Commit, tag string) (AnalyzedCommit, bo } } - log.Tracef("%s does not match %s, skip", commit.Message, tag) + log.Tracef("%s does not match %s, skip", commit.Message, rule.Tag) return analyzed, false, fmt.Errorf("Not found") } diff --git a/internal/changelog/changelog.go b/internal/changelog/changelog.go new file mode 100644 index 0000000..75ffd73 --- /dev/null +++ b/internal/changelog/changelog.go @@ -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 +} diff --git a/pkg/config/config.go b/pkg/config/config.go index 2ad014c..44d56d2 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -10,7 +10,7 @@ import ( // ChangelogConfig struct type ChangelogConfig struct { - Print string `yaml:"print,omitempty"` + PrintAll bool `yaml:"printAll,omitempty"` Template string `yaml:"template,omitempty"` TemplatePath string `yaml:"templatePath,omitempty"` } diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index 94b1de2..f44b27c 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -2,13 +2,14 @@ package semanticrelease import ( - "fmt" + "io/ioutil" "strconv" "strings" "github.com/Masterminds/semver" "github.com/Nightapes/go-semantic-release/internal/analyzer" "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/pkg/config" log "github.com/sirupsen/logrus" @@ -27,15 +28,15 @@ func New(c *config.ReleaseConfig) *SemanticRelease { } // 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) if err != nil { - return err + return "", err } hash, err := util.GetHash() if err != nil { - return err + return "", err } log.Debugf("Ignore .version file if exits, %t", force) @@ -44,15 +45,14 @@ func (s *SemanticRelease) GetNextVersion(repro string, force bool) error { if err == nil && content.Commit == hash { log.Infof("Found cache, will return cached version %s", content.NextVersion) - fmt.Printf(content.NextVersion) - return nil + return content.NextVersion, err } log.Debugf("Mismatch git and version file %s - %s", content.Commit, hash) } lastVersion, lastVersionHash, err := util.GetLastVersion() if err != nil { - return err + return "", err } var newVersion semver.Version @@ -65,17 +65,17 @@ func (s *SemanticRelease) GetNextVersion(repro string, force bool) error { commits, err := util.GetCommits(lastVersionHash) if err != nil { - return err + return "", err } 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) currentBranch, err := util.GetBranch() if err != nil { - return err + return "", err } for branch, releaseType := range s.config.Branch { @@ -99,11 +99,12 @@ func (s *SemanticRelease) GetNextVersion(repro string, force bool) error { log.Infof("New version %s -> %s", lastVersion.String(), newVersion.String()) err = saveToCache(util, lastVersion, &newVersion) if err != nil { - return err + return "", err } - fmt.Printf("%s", newVersion.String()) + c := changelog.New(s.config) + c.GenerateChanglog(newVersion.String(), result) - return err + return newVersion.String(), err } //SetVersion for git repository @@ -175,3 +176,38 @@ func incPrerelease(preReleaseType string, version semver.Version) semver.Version 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) + +} From 1c9b6d5c41b426e1d5975e00d86c9251d914b45b Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Tue, 28 May 2019 18:44:27 +0200 Subject: [PATCH 12/77] tmp(releser, github-provider): add releaser and github as first release provider --- internal/releaser/releaser.go | 36 +++++++++++++++++++++++++++ internal/releaser/releasers/github.go | 36 +++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 internal/releaser/releaser.go create mode 100644 internal/releaser/releasers/github.go diff --git a/internal/releaser/releaser.go b/internal/releaser/releaser.go new file mode 100644 index 0000000..6402c6e --- /dev/null +++ b/internal/releaser/releaser.go @@ -0,0 +1,36 @@ +package releaser + +import ( + "fmt" + "github.com/Nightapes/go-semantic-release/internal/cache" + "github.com/Nightapes/go-semantic-release/internal/releaser/releasers" + "github.com/Nightapes/go-semantic-release/pkg/config" +) + +// Releasers struct type +type Releasers struct { + config *config.ReleaseConfig +} + +// Releaser interface for providers +type Releaser interface { + CreateRelease(releaseName, releaseMessage string) error +} + +// New initialize a Relerser +func New(c *config.ReleaseConfig) *Releasers { + return &Releasers{ + config: c, + } +} + +//GetReleaser returns an initialized releaser +func (r *Releasers) GetReleaser(releaserType string) (Releaser, error) { + switch releaserType { + case releasers.GITHUB: + return releasers.NewGitHubReleaser(r.config), nil + } + return nil, fmt.Errorf("Could not initialize a releaser from this type: %s", releaserType) +} + +// tbd. http helper function diff --git a/internal/releaser/releasers/github.go b/internal/releaser/releasers/github.go new file mode 100644 index 0000000..3b65c53 --- /dev/null +++ b/internal/releaser/releasers/github.go @@ -0,0 +1,36 @@ +package releasers + +import ( + "github.com/Nightapes/go-semantic-release/pkg/config" +) + +// GITHUB identifer for github interface +const GITHUB = "github" + +// GitHubReleaser type struct +type GitHubReleaser struct { + RepositoryURL string + TagName string `json:"tag_name"` + TargetCommitish string `json:"target_commitish"` + ReleaseName string `json:"name"` + ReleaseMessage string `json:"body"` + Draft bool `json:"draft,omitempty"` + Prerelease bool `json:"prerelease,omitempty"` + // Assets +} + +// CreateRelease creates release on remote +func (g *GitHubReleaser) CreateRelease(releaseName, releaseMessage string) error { + g.ReleaseName = releaseName + g.ReleaseMessage = releaseMessage + return nil +} + +// NewGitHubReleaser initialize a new GitHubRelease +func NewGitHubReleaser(c *config.ReleaseConfig, branch, latestVersion string) *GitHubReleaser { + return &GitHubReleaser{ + RepositoryURL: c.Github["url"], + TargetCommitish: branch, + TagName: latestVersion, + } +} From 29a97cbba4447406c238c84579bba16bf8ce875f Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Tue, 28 May 2019 22:12:00 +0200 Subject: [PATCH 13/77] feat(config): add list of assets with name and bool if the asset should be compressed --- .release.yml | 3 +++ pkg/config/config.go | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/.release.yml b/.release.yml index 730a27a..eb9ed36 100644 --- a/.release.yml +++ b/.release.yml @@ -9,6 +9,9 @@ changelog: template: '' templatePath: '' release: 'github' +assets: + - name: + compress: github: url: '' gitlab: diff --git a/pkg/config/config.go b/pkg/config/config.go index 44d56d2..f37525d 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -25,6 +25,11 @@ type GitlabConfig struct { URL string `yaml:"url"` } +type Asset struct { + Name string `yaml:"name"` + Compress bool `yaml:"compress"` +} + // ReleaseConfig struct type ReleaseConfig struct { CommitFormat string `yaml:"commitFormat"` @@ -33,6 +38,7 @@ type ReleaseConfig struct { Release string `yaml:"release,omitempty"` Github map[string]string `yaml:"github"` Gitlab map[string]string `yaml:"gitlab"` + Assets []Asset `yaml:"assets"` } // Read ReleaseConfig From 17f715becad91edf6f58a10dfc8bad44d9b6173a Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Tue, 28 May 2019 22:12:45 +0200 Subject: [PATCH 14/77] tmp(releaser): add helper methods for releasers --- internal/releaser/github.go | 82 +++++++++++++++++++++++++ internal/releaser/releaser.go | 86 +++++++++++++++++++++++++-- internal/releaser/releasers/github.go | 36 ----------- 3 files changed, 164 insertions(+), 40 deletions(-) create mode 100644 internal/releaser/github.go delete mode 100644 internal/releaser/releasers/github.go diff --git a/internal/releaser/github.go b/internal/releaser/github.go new file mode 100644 index 0000000..e46cd47 --- /dev/null +++ b/internal/releaser/github.go @@ -0,0 +1,82 @@ +package releaser + +import ( + "encoding/json" + "fmt" + "github.com/Nightapes/go-semantic-release/pkg/config" + "io/ioutil" + "strings" +) + +// GITHUB identifer for github interface +const GITHUB = "github" +const githubCreateRleasURL = "https://api.github.com/repos" +const githubUploadAssetURL = "https://uploads.github.com" + +// GitHubReleaser type struct +type GitHubReleaser struct { + repositoryURL string + authToken string + assets []config.Asset + Version string `json:"tag_name"` + Branch string `json:"target_commitish"` + ReleaseName string `json:"name"` + ReleaseMessage string `json:"body"` + Draft bool `json:"draft,omitempty"` + Prerelease bool `json:"prerelease,omitempty"` +} + +type gitHubCreateReleaseResponse struct { + ReleaseURL string `json:url` + AssetUploadURL string `json:upload_url` +} + +// NewGitHubReleaser initialize a new GitHubRelease +func NewGitHubReleaser(c *config.ReleaseConfig) *GitHubReleaser { + return &GitHubReleaser{ + repositoryURL: c.Github["url"], + authToken: c.Github["authToken"], + assets: c.Assets, + } +} + +// CreateRelease creates release on remote +func (g *GitHubReleaser) CreateRelease(releaseName, releaseMessage, branch, version string) error { + g.ReleaseName = releaseName + g.ReleaseMessage = releaseMessage + g.Branch = branch + g.Version = version + + repositoryURI := strings.TrimLeft(g.repositoryURL, "/") + jsonRelease, err := json.Marshal(g) + + if err != nil { + return fmt.Errorf("releaser: github: could not marshal GitHubReleaser struct. Error: %s", err.Error()) + } + + tempDir, err := ioutil.TempDir(".", "tempZipAssets") + if err != nil { + return fmt.Errorf("releaser: github: Could not create a temp directory. Error: %s", err.Error()) + } + assetList, err := prepareAssets(tempDir, g.assets) + if err != nil { + return err + } + + response, err := makeReleaseRequest(githubCreateRleasURL+repositoryURI, g.authToken, jsonRelease) + if err != nil { + return err + } + + releaseInfo := gitHubCreateReleaseResponse{} + if err := json.Unmarshal(response, &releaseInfo); err != nil { + return err + } + + // tbd build new upload url + if err := uploadReleaseAssets(releaseInfo.AssetUploadURL, g.authToken, assetList); err != nil { + return err + } + + return nil +} diff --git a/internal/releaser/releaser.go b/internal/releaser/releaser.go index 6402c6e..adec996 100644 --- a/internal/releaser/releaser.go +++ b/internal/releaser/releaser.go @@ -1,10 +1,12 @@ package releaser import ( + "archive/zip" + "bytes" "fmt" - "github.com/Nightapes/go-semantic-release/internal/cache" - "github.com/Nightapes/go-semantic-release/internal/releaser/releasers" "github.com/Nightapes/go-semantic-release/pkg/config" + "io/ioutil" + "net/http" ) // Releasers struct type @@ -27,10 +29,86 @@ func New(c *config.ReleaseConfig) *Releasers { //GetReleaser returns an initialized releaser func (r *Releasers) GetReleaser(releaserType string) (Releaser, error) { switch releaserType { - case releasers.GITHUB: - return releasers.NewGitHubReleaser(r.config), nil + case GITHUB: + return NewGitHubReleaser(r.config), nil } return nil, fmt.Errorf("Could not initialize a releaser from this type: %s", releaserType) } // tbd. http helper function + +func makeReleaseRequest(url, authToken string, jsonRelease []byte) ([]byte, error) { + request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(jsonRelease)) + request.Header.Set("Authorization", authToken) + request.Header.Set("content-type", "application/json") + + client := http.Client{} + defer client.CloseIdleConnections() + + response, err := client.Do(request) + + if err != nil { + return []byte{}, err + + } + bodyContent, _ := ioutil.ReadAll(response.Body) + + if response.StatusCode >= http.StatusMultipleChoices { + return []byte{}, fmt.Errorf("Could not create new release. HTTP %d: %s", response.StatusCode, string(bodyContent)) + } + + return bodyContent, nil +} + +func uploadReleaseAssets(url, authToken string, assets []string) error { + body := []byte{} + request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(body)) + + request.Header.Set("Authorization", authToken) + client := http.Client{} + defer client.CloseIdleConnections() + + response, err := client.Do(request) + + if err != nil { + return err + + } + bodyContent, _ := ioutil.ReadAll(response.Body) + + if response.StatusCode >= http.StatusMultipleChoices { + return fmt.Errorf("Could not create new release. HTTP %d: %s", response.StatusCode, string(bodyContent)) + } + + return nil +} + +func prepareAssets(tempDir string, asset []config.Asset) ([]string, error) { + buf := new(bytes.Buffer) + tempAssets := []string{} + for _, asset := range asset { + if asset.Compress { + fileContent, err := ioutil.ReadFile(asset.Name) + if err != nil { + return []string{}, err + } + + w := zip.NewWriter(buf) + zip, err := w.Create(tempDir + asset.Name) + + if err != nil { + return []string{}, err + } + + _, err = zip.Write(fileContent) + if err != nil { + return []string{}, err + } + tempAssets = append(tempAssets, tempDir+asset.Name) + + } else { + tempAssets = append(tempAssets, asset.Name) + } + } + return tempAssets, nil +} diff --git a/internal/releaser/releasers/github.go b/internal/releaser/releasers/github.go deleted file mode 100644 index 3b65c53..0000000 --- a/internal/releaser/releasers/github.go +++ /dev/null @@ -1,36 +0,0 @@ -package releasers - -import ( - "github.com/Nightapes/go-semantic-release/pkg/config" -) - -// GITHUB identifer for github interface -const GITHUB = "github" - -// GitHubReleaser type struct -type GitHubReleaser struct { - RepositoryURL string - TagName string `json:"tag_name"` - TargetCommitish string `json:"target_commitish"` - ReleaseName string `json:"name"` - ReleaseMessage string `json:"body"` - Draft bool `json:"draft,omitempty"` - Prerelease bool `json:"prerelease,omitempty"` - // Assets -} - -// CreateRelease creates release on remote -func (g *GitHubReleaser) CreateRelease(releaseName, releaseMessage string) error { - g.ReleaseName = releaseName - g.ReleaseMessage = releaseMessage - return nil -} - -// NewGitHubReleaser initialize a new GitHubRelease -func NewGitHubReleaser(c *config.ReleaseConfig, branch, latestVersion string) *GitHubReleaser { - return &GitHubReleaser{ - RepositoryURL: c.Github["url"], - TargetCommitish: branch, - TagName: latestVersion, - } -} From 2dd59be36222ef712a69d9c11b9cb8a1bcd86ace Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Wed, 5 Jun 2019 22:20:42 +0200 Subject: [PATCH 15/77] ref(releaser/github): uses now the google github libary --- go.mod | 3 +- internal/releaser/github.go | 89 ++++++++++++++++++----------------- internal/releaser/releaser.go | 88 ++++++++-------------------------- 3 files changed, 67 insertions(+), 113 deletions(-) diff --git a/go.mod b/go.mod index 89ee791..9a92235 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,9 @@ require ( github.com/Masterminds/semver v1.4.2 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect + github.com/google/go-github/v25 v25.1.1 github.com/sirupsen/logrus v1.4.1 - golang.org/x/net v0.0.0-20190311183353-d8887717615a // indirect + golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be gopkg.in/alecthomas/kingpin.v2 v2.2.6 gopkg.in/src-d/go-git.v4 v4.11.0 gopkg.in/yaml.v2 v2.2.2 diff --git a/internal/releaser/github.go b/internal/releaser/github.go index e46cd47..475b19a 100644 --- a/internal/releaser/github.go +++ b/internal/releaser/github.go @@ -1,29 +1,23 @@ package releaser import ( - "encoding/json" + "context" "fmt" "github.com/Nightapes/go-semantic-release/pkg/config" - "io/ioutil" - "strings" + "github.com/google/go-github/v25/github" + "net/http" + "os" ) // GITHUB identifer for github interface const GITHUB = "github" -const githubCreateRleasURL = "https://api.github.com/repos" -const githubUploadAssetURL = "https://uploads.github.com" // GitHubReleaser type struct type GitHubReleaser struct { - repositoryURL string - authToken string - assets []config.Asset - Version string `json:"tag_name"` - Branch string `json:"target_commitish"` - ReleaseName string `json:"name"` - ReleaseMessage string `json:"body"` - Draft bool `json:"draft,omitempty"` - Prerelease bool `json:"prerelease,omitempty"` + config *config.ReleaseConfig + client *github.Client + context context.Context + release *github.RepositoryRelease } type gitHubCreateReleaseResponse struct { @@ -33,50 +27,57 @@ type gitHubCreateReleaseResponse struct { // NewGitHubReleaser initialize a new GitHubRelease func NewGitHubReleaser(c *config.ReleaseConfig) *GitHubReleaser { + ctx := context.Background() + httpClient := createHTTPClient(ctx, c.Github.AccessToken) + return &GitHubReleaser{ - repositoryURL: c.Github["url"], - authToken: c.Github["authToken"], - assets: c.Assets, + config: c, + client: github.NewClient(httpClient), + context: ctx, } } // CreateRelease creates release on remote -func (g *GitHubReleaser) CreateRelease(releaseName, releaseMessage, branch, version string) error { - g.ReleaseName = releaseName - g.ReleaseMessage = releaseMessage - g.Branch = branch - g.Version = version +func (g GitHubReleaser) CreateRelease(tag, releaseName, releaseMessage, targetBranch string) error { - repositoryURI := strings.TrimLeft(g.repositoryURL, "/") - jsonRelease, err := json.Marshal(g) + release, resp, err := g.client.Repositories.CreateRelease(g.context, g.config.Github.User, g.config.Github.URL, &github.RepositoryRelease{ + TagName: &tag, + TargetCommitish: &targetBranch, + Name: &releaseName, + Body: &releaseMessage, + Draft: &g.config.IsDraft, + Prerelease: &g.config.IsPreRelease, + }) if err != nil { - return fmt.Errorf("releaser: github: could not marshal GitHubReleaser struct. Error: %s", err.Error()) + return fmt.Errorf("releaser: github: Could not create release: %v", err) } - tempDir, err := ioutil.TempDir(".", "tempZipAssets") - if err != nil { - return fmt.Errorf("releaser: github: Could not create a temp directory. Error: %s", err.Error()) - } - assetList, err := prepareAssets(tempDir, g.assets) - if err != nil { - return err + if resp.StatusCode >= http.StatusBadRequest { + return fmt.Errorf("releaser: github: Could not create release: response statuscode: %s", resp.Status) } - response, err := makeReleaseRequest(githubCreateRleasURL+repositoryURI, g.authToken, jsonRelease) - if err != nil { - return err - } + g.release = release + return nil - releaseInfo := gitHubCreateReleaseResponse{} - if err := json.Unmarshal(response, &releaseInfo); err != nil { - return err - } +} - // tbd build new upload url - if err := uploadReleaseAssets(releaseInfo.AssetUploadURL, g.authToken, assetList); err != nil { - return err - } +// UploadAssets uploads specified assets +func (g GitHubReleaser) UploadAssets(assets []config.Asset) error { + for _, asset := range assets { + file, err := os.Open(asset.Name) + if err != nil { + return err + } + _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.Github.User, g.config.Github.URL, *g.release.ID, &github.UploadOptions{Name: asset.Name}, file) + if err != nil { + return err + } + + if resp.StatusCode >= http.StatusBadRequest { + return fmt.Errorf("releaser: github: Could not create release: response statuscode: %s", resp.Status) + } + } return nil } diff --git a/internal/releaser/releaser.go b/internal/releaser/releaser.go index adec996..4541a50 100644 --- a/internal/releaser/releaser.go +++ b/internal/releaser/releaser.go @@ -1,12 +1,12 @@ package releaser import ( - "archive/zip" - "bytes" + "context" "fmt" "github.com/Nightapes/go-semantic-release/pkg/config" - "io/ioutil" + "golang.org/x/oauth2" "net/http" + "os" ) // Releasers struct type @@ -16,7 +16,8 @@ type Releasers struct { // Releaser interface for providers type Releaser interface { - CreateRelease(releaseName, releaseMessage string) error + CreateRelease(tag, releaseName, releaseMessage, targetBranch string) error + UploadAssets(assets []config.Asset) error } // New initialize a Relerser @@ -37,78 +38,29 @@ func (r *Releasers) GetReleaser(releaserType string) (Releaser, error) { // tbd. http helper function -func makeReleaseRequest(url, authToken string, jsonRelease []byte) ([]byte, error) { - request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(jsonRelease)) - request.Header.Set("Authorization", authToken) - request.Header.Set("content-type", "application/json") +func createHTTPClient(ctx context.Context, token string) *http.Client { + tokenSource := oauth2.StaticTokenSource(&oauth2.Token{ + AccessToken: token}, + ) - client := http.Client{} - defer client.CloseIdleConnections() + client := oauth2.NewClient(ctx, tokenSource) - response, err := client.Do(request) - - if err != nil { - return []byte{}, err - - } - bodyContent, _ := ioutil.ReadAll(response.Body) - - if response.StatusCode >= http.StatusMultipleChoices { - return []byte{}, fmt.Errorf("Could not create new release. HTTP %d: %s", response.StatusCode, string(bodyContent)) - } - - return bodyContent, nil + return client } -func uploadReleaseAssets(url, authToken string, assets []string) error { - body := []byte{} - request, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(body)) - - request.Header.Set("Authorization", authToken) - client := http.Client{} - defer client.CloseIdleConnections() - - response, err := client.Do(request) - - if err != nil { - return err +func checkIfAssetsExists(assets []config.Asset) error { + var missingAssets []string + for _, asset := range assets { + if _, err := os.Stat(asset.Name); err != nil { + missingAssets = append(missingAssets, asset.Name) + } } - bodyContent, _ := ioutil.ReadAll(response.Body) - if response.StatusCode >= http.StatusMultipleChoices { - return fmt.Errorf("Could not create new release. HTTP %d: %s", response.StatusCode, string(bodyContent)) + if len(missingAssets) != 0 { + return fmt.Errorf("Could not find specified Asset: %+v ", assets) } return nil -} - -func prepareAssets(tempDir string, asset []config.Asset) ([]string, error) { - buf := new(bytes.Buffer) - tempAssets := []string{} - for _, asset := range asset { - if asset.Compress { - fileContent, err := ioutil.ReadFile(asset.Name) - if err != nil { - return []string{}, err - } - - w := zip.NewWriter(buf) - zip, err := w.Create(tempDir + asset.Name) - - if err != nil { - return []string{}, err - } - - _, err = zip.Write(fileContent) - if err != nil { - return []string{}, err - } - tempAssets = append(tempAssets, tempDir+asset.Name) - - } else { - tempAssets = append(tempAssets, asset.Name) - } - } - return tempAssets, nil + } From 4011cd5a8c345203f4147025886b7c6a08879b2b Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Wed, 5 Jun 2019 22:22:06 +0200 Subject: [PATCH 16/77] feat(config): add option for draft, prerelease, provider: user, accesstoken --- pkg/config/config.go | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index f37525d..55b8b18 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -17,12 +17,16 @@ type ChangelogConfig struct { // GithubConfig struct type GithubConfig struct { - URL string `yaml:"url"` + URL string `yaml:"url"` + User string `yaml:"user"` + AccessToken string `yaml:"accessToken"` } // GitlabConfig struct type GitlabConfig struct { - URL string `yaml:"url"` + URL string `yaml:"url"` + User string `yaml:"user"` + AccessToken string `yaml:"accessToken"` } type Asset struct { @@ -32,13 +36,14 @@ type Asset struct { // ReleaseConfig struct type ReleaseConfig struct { - CommitFormat string `yaml:"commitFormat"` - Branch map[string]string `yaml:"branch"` - Changelog ChangelogConfig `yaml:"changelog,omitempty"` - Release string `yaml:"release,omitempty"` - Github map[string]string `yaml:"github"` - Gitlab map[string]string `yaml:"gitlab"` - Assets []Asset `yaml:"assets"` + CommitFormat string `yaml:"commitFormat"` + Branch map[string]string `yaml:"branch"` + Changelog ChangelogConfig `yaml:"changelog,omitempty"` + Release string `yaml:"release,omitempty"` + Github GitlabConfig `yaml:"github, omitempty"` + Gitlab GitlabConfig `yaml:"gitlab, omitempty"` + Assets []Asset `yaml:"assets"` + IsPreRelease, IsDraft bool } // Read ReleaseConfig @@ -57,5 +62,7 @@ func Read(configPath string) (*ReleaseConfig, error) { log.Debugf("Found config %+v", releaseConfig) - return &releaseConfig, nil + return &ReleaseConfig{ + IsPreRelease: false, + IsDraft: false}, nil } From a1498f3e3234d62129cec2dbd78b6c90680aed6c Mon Sep 17 00:00:00 2001 From: Nightapes Date: Mon, 10 Jun 2019 16:24:44 +0200 Subject: [PATCH 17/77] feat(changelog): add order and hash url --- .gitignore | 1 + README.md | 10 +++++ go.sum | 12 ++++++ internal/analyzer/analyzer.go | 38 ++++++++++------- internal/analyzer/angular.go | 2 +- internal/changelog/changelog.go | 56 +++++++++++++++++++------ pkg/config/config.go | 8 ++-- pkg/semanticrelease/semantic-release.go | 23 ++++++---- 8 files changed, 110 insertions(+), 40 deletions(-) diff --git a/.gitignore b/.gitignore index ad23d73..7c8f013 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ go-semantic-release *.out .version .vscode/settings.json +CHANGELOG.md diff --git a/README.md b/README.md index b124392..85aa0c4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,15 @@ # go-semantic-release +## Release Types + +| Type | Git tag | Changelog | Release | Write access git | Api token | +|--- |:---: |:---: |:---: |:---: |:---: | +| `git` | :white_check_mark: | | | :white_check_mark:| | +| `github` | :white_check_mark: | :white_check_mark: | :white_check_mark:| | :white_check_mark: | +| `gitlab` | :white_check_mark: | :white_check_mark: | :white_check_mark:| | :white_check_mark: | + + + ## Build `go build ./cmd/go-semantic-release/` diff --git a/go.sum b/go.sum index 1561e63..39e2eec 100644 --- a/go.sum +++ b/go.sum @@ -16,8 +16,14 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjr github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-github/v25 v25.1.1 h1:6eW++i/CXcR5GKfYaaJT7oJJtHNU+/iiw55noEPNVao= +github.com/google/go-github/v25 v25.1.1/go.mod h1:6z5pC69qHtrPJ0sXPsj4BLnd82b+r6sLB7qcBoRZqpw= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -57,6 +63,10 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9 h1:lkiLiLBHGoH3XnqSLUIaBsilGMUjI+Uy2Xu2JLUtTas= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -64,6 +74,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go index 10f2cc3..60e7e56 100644 --- a/internal/analyzer/analyzer.go +++ b/internal/analyzer/analyzer.go @@ -2,6 +2,8 @@ package analyzer import ( + "fmt" + "github.com/Nightapes/go-semantic-release/internal/gitutil" "github.com/Nightapes/go-semantic-release/pkg/config" log "github.com/sirupsen/logrus" @@ -9,8 +11,8 @@ import ( //Analyzer struct type Analyzer struct { - CommitFormat string - Config config.ChangelogConfig + analyzeCommit analyzeCommit + Config config.ChangelogConfig } //Rule for commits @@ -38,24 +40,30 @@ type AnalyzedCommit struct { } //New Analyzer struct for given commit format -func New(format string, config config.ChangelogConfig) *Analyzer { - return &Analyzer{ - CommitFormat: format, - Config: config, +func New(format string, config config.ChangelogConfig) (*Analyzer, error) { + analyzer := &Analyzer{ + Config: config, } + switch format { + case "angular": + log.Debugf("Commit format set to angular") + analyzer.analyzeCommit = newAngular() + default: + return nil, fmt.Errorf("Invalid commit format: %s", format) + } + return analyzer, nil + +} + +// GetRules from current mode +func (a *Analyzer) GetRules() []Rule { + return a.analyzeCommit.getRules() } // Analyze commits and return commits splitted by major,minor,patch func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit { - var commitAnalayzer analyzeCommit - switch a.CommitFormat { - case "angular": - log.Debugf("Commit format set to angular") - commitAnalayzer = newAngular() - } - analyzedCommits := make(map[string][]AnalyzedCommit) analyzedCommits["major"] = make([]AnalyzedCommit, 0) analyzedCommits["minor"] = make([]AnalyzedCommit, 0) @@ -63,8 +71,8 @@ func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit analyzedCommits["none"] = make([]AnalyzedCommit, 0) for _, commit := range commits { - for _, rule := range commitAnalayzer.getRules() { - analyzedCommit, hasBreakingChange, err := commitAnalayzer.analyze(commit, rule) + for _, rule := range a.analyzeCommit.getRules() { + analyzedCommit, hasBreakingChange, err := a.analyzeCommit.analyze(commit, rule) if err == nil { if a.Config.PrintAll { analyzedCommit.Print = true diff --git a/internal/analyzer/angular.go b/internal/analyzer/angular.go index 41e09c0..d05cff5 100644 --- a/internal/analyzer/angular.go +++ b/internal/analyzer/angular.go @@ -64,7 +64,7 @@ func newAngular() *angular { Changelog: false, }, { Tag: "build", - TagString: "Changes to ci config", + TagString: "Changes to CI/CD", Release: "none", Changelog: false, }, diff --git a/internal/changelog/changelog.go b/internal/changelog/changelog.go index 75ffd73..eed9d11 100644 --- a/internal/changelog/changelog.go +++ b/internal/changelog/changelog.go @@ -2,48 +2,65 @@ package changelog import ( "bytes" + "strings" "text/template" "time" "github.com/Nightapes/go-semantic-release/internal/analyzer" "github.com/Nightapes/go-semantic-release/pkg/config" + + log "github.com/sirupsen/logrus" ) 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 }} +const defaultChangelog string = `# v{{$.Version}} ({{.Now.Format "2006-01-02"}}) +{{ range $key := .Order }} +{{ $commits := index $.Commits $key}} {{if $commits -}} ### {{ $key }} - -{{range $index,$commit := $commits}}* **{{$backtick}}{{$commit.Scope}}:{{$backtick}}** {{$commit.ParsedMessage}} +{{ range $index,$commit := $commits -}} +* **{{$.Backtick}}{{$commit.Scope}}{{$.Backtick}}** {{$commit.ParsedMessage}} {{if $.HasURL}} ([{{ printf "%.7s" $commit.Commit.Hash}}]({{ replace $.URL "{{hash}}" $commit.Commit.Hash}})) {{end}} +{{ end -}} {{ end -}} {{ end -}} ` type changelogContent struct { Commits map[string][]analyzer.AnalyzedCommit + Order []string Version string Now time.Time Backtick string + HasURL bool + URL string } -//CommitFormat struct +//Changelog struct type Changelog struct { config *config.ReleaseConfig + rules []analyzer.Rule } //New Changelog struct for generating changelog from commits -func New(config *config.ReleaseConfig) *Changelog { +func New(config *config.ReleaseConfig, rules []analyzer.Rule) *Changelog { return &Changelog{ config: config, + rules: rules, } } // GenerateChanglog from given commits -func (c *Changelog) GenerateChanglog(version string, analyzedCommits map[string][]analyzer.AnalyzedCommit) (string, string, error) { +func (c *Changelog) GenerateChanglog(version, url string, analyzedCommits map[string][]analyzer.AnalyzedCommit) (string, string, error) { commitsPerScope := map[string][]analyzer.AnalyzedCommit{} + order := make([]string, 0) + + for _, rule := range c.rules { + log.Debugf("Add %s to list", rule.TagString) + if rule.Changelog || c.config.Changelog.PrintAll { + order = append(order, rule.TagString) + } + } + for _, commits := range analyzedCommits { for _, commit := range commits { if commit.Print { @@ -60,23 +77,38 @@ func (c *Changelog) GenerateChanglog(version string, analyzedCommits map[string] Commits: commitsPerScope, Now: time.Now(), Backtick: "`", + Order: order, + HasURL: url != "", + URL: url, } title, err := generateTemplate(defaultChangelogTitle, changelogContent) + if err != nil { + return "", "", err + } content, err := generateTemplate(defaultChangelog, changelogContent) return title, content, err } func generateTemplate(text string, values changelogContent) (string, error) { + + funcMap := template.FuncMap{ + "replace": replace, + } + var tpl bytes.Buffer - tmpl, err := template.New("template").Parse(text) + tmpl, err := template.New("template").Funcs(funcMap).Parse(text) if err != nil { - return "", nil + return "", err } err = tmpl.Execute(&tpl, values) if err != nil { - return "", nil + return "", err } return tpl.String(), nil } + +func replace(input, from, to string) string { + return strings.Replace(input, from, to, -1) +} diff --git a/pkg/config/config.go b/pkg/config/config.go index 55b8b18..70fdb80 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -40,8 +40,8 @@ type ReleaseConfig struct { Branch map[string]string `yaml:"branch"` Changelog ChangelogConfig `yaml:"changelog,omitempty"` Release string `yaml:"release,omitempty"` - Github GitlabConfig `yaml:"github, omitempty"` - Gitlab GitlabConfig `yaml:"gitlab, omitempty"` + Github GitlabConfig `yaml:"github,omitempty"` + Gitlab GitlabConfig `yaml:"gitlab,omitempty"` Assets []Asset `yaml:"assets"` IsPreRelease, IsDraft bool } @@ -62,7 +62,5 @@ func Read(configPath string) (*ReleaseConfig, error) { log.Debugf("Found config %+v", releaseConfig) - return &ReleaseConfig{ - IsPreRelease: false, - IsDraft: false}, nil + return &releaseConfig, nil } diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index f44b27c..036182d 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -59,6 +59,7 @@ func (s *SemanticRelease) GetNextVersion(repro string, force bool) (string, erro if lastVersion == nil { defaultVersion, _ := semver.NewVersion("1.0.0") newVersion = *defaultVersion + lastVersion = defaultVersion } else { newVersion = *lastVersion } @@ -70,7 +71,10 @@ func (s *SemanticRelease) GetNextVersion(repro string, force bool) (string, erro log.Debugf("Found %d commits till last release", len(commits)) - a := analyzer.New(s.config.CommitFormat, s.config.Changelog) + a, err := analyzer.New(s.config.CommitFormat, s.config.Changelog) + if err != nil { + return "", err + } result := a.Analyze(commits) currentBranch, err := util.GetBranch() @@ -101,8 +105,8 @@ func (s *SemanticRelease) GetNextVersion(repro string, force bool) (string, erro if err != nil { return "", err } - c := changelog.New(s.config) - c.GenerateChanglog(newVersion.String(), result) + c := changelog.New(s.config, a.GetRules()) + c.GenerateChanglog(newVersion.String(), "https://github.com/Nightapes/go-semantic-release/commit/{{hash}}", result) return newVersion.String(), err } @@ -202,12 +206,17 @@ func (s *SemanticRelease) GetChangelog(repro, file string) error { log.Debugf("Found %d commits till last release", len(commits)) - a := analyzer.New(s.config.CommitFormat, s.config.Changelog) + a, err := analyzer.New(s.config.CommitFormat, s.config.Changelog) + if err != nil { + return err + } result := a.Analyze(commits) - c := changelog.New(s.config) - _, content, err := c.GenerateChanglog(nextVersion, result) - + c := changelog.New(s.config, a.GetRules()) + _, content, err := c.GenerateChanglog(nextVersion, "https://github.com/Nightapes/go-semantic-release/commit/{{hash}}", result) + if err != nil { + return err + } return ioutil.WriteFile(file, []byte(content), 0644) } From 63ea1e00a34de5dd013c5c09934f9febdd0a24d6 Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 13 Jun 2019 18:19:14 +0200 Subject: [PATCH 18/77] update(go.sum): update --- go.sum | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/go.sum b/go.sum index 1561e63..4e559a7 100644 --- a/go.sum +++ b/go.sum @@ -16,8 +16,13 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjr github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-github/v25 v25.1.1 h1:6eW++i/CXcR5GKfYaaJT7oJJtHNU+/iiw55noEPNVao= +github.com/google/go-github/v25 v25.1.1/go.mod h1:6z5pC69qHtrPJ0sXPsj4BLnd82b+r6sLB7qcBoRZqpw= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -57,6 +62,9 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9 h1:lkiLiLBHGoH3XnqSLUIaBsilGMUjI+Uy2Xu2JLUtTas= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -64,6 +72,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 882a1f4c29c6231ac7b2081f0319654e88c97588 Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 13 Jun 2019 19:31:56 +0200 Subject: [PATCH 19/77] feat(config/releaserconfig): change git provider from several type structs to one for simplicity --- internal/releaser/github.go | 2 +- internal/releaser/releaser.go | 6 ++--- pkg/config/config.go | 41 +++++++++++++++++++++++++---------- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/internal/releaser/github.go b/internal/releaser/github.go index 475b19a..62197d7 100644 --- a/internal/releaser/github.go +++ b/internal/releaser/github.go @@ -10,7 +10,7 @@ import ( ) // GITHUB identifer for github interface -const GITHUB = "github" +const GITHUB = "GitHub" // GitHubReleaser type struct type GitHubReleaser struct { diff --git a/internal/releaser/releaser.go b/internal/releaser/releaser.go index 4541a50..3e095bb 100644 --- a/internal/releaser/releaser.go +++ b/internal/releaser/releaser.go @@ -28,12 +28,12 @@ func New(c *config.ReleaseConfig) *Releasers { } //GetReleaser returns an initialized releaser -func (r *Releasers) GetReleaser(releaserType string) (Releaser, error) { - switch releaserType { +func (r *Releasers) GetReleaser() (Releaser, error) { + switch r.config.GitProvider.Name { case GITHUB: return NewGitHubReleaser(r.config), nil } - return nil, fmt.Errorf("Could not initialize a releaser from this type: %s", releaserType) + return nil, fmt.Errorf("Could not initialize a releaser from this type: %s", r.config.GitProvider.Name) } // tbd. http helper function diff --git a/pkg/config/config.go b/pkg/config/config.go index 70fdb80..b0a35f5 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -2,12 +2,18 @@ package config import ( + "fmt" "io/ioutil" + "os" + "strings" log "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" ) +// List of all supported git providers +var gitPorviders = map[string]string{"GitHub": "", "GitLab": ""} + // ChangelogConfig struct type ChangelogConfig struct { PrintAll bool `yaml:"printAll,omitempty"` @@ -15,15 +21,9 @@ type ChangelogConfig struct { TemplatePath string `yaml:"templatePath,omitempty"` } -// GithubConfig struct -type GithubConfig struct { - URL string `yaml:"url"` - User string `yaml:"user"` - AccessToken string `yaml:"accessToken"` -} - -// GitlabConfig struct -type GitlabConfig struct { +// GitProvider struct +type GitProvider struct { + Name string `yaml:"name"` URL string `yaml:"url"` User string `yaml:"user"` AccessToken string `yaml:"accessToken"` @@ -40,8 +40,7 @@ type ReleaseConfig struct { Branch map[string]string `yaml:"branch"` Changelog ChangelogConfig `yaml:"changelog,omitempty"` Release string `yaml:"release,omitempty"` - Github GitlabConfig `yaml:"github,omitempty"` - Gitlab GitlabConfig `yaml:"gitlab,omitempty"` + GitProvider GitProvider `yaml:"provider,omitempty"` Assets []Asset `yaml:"assets"` IsPreRelease, IsDraft bool } @@ -62,5 +61,25 @@ func Read(configPath string) (*ReleaseConfig, error) { log.Debugf("Found config %+v", releaseConfig) + releaseConfig, err = checkProvider(releaseConfig) + if err != nil { + return &ReleaseConfig{}, err + } return &releaseConfig, nil } + +func checkProvider(config ReleaseConfig) (ReleaseConfig, error) { + if config.GitProvider != (GitProvider{}) { + if _, ok := gitPorviders[config.GitProvider.Name]; !ok { + return ReleaseConfig{}, fmt.Errorf("config: provider: configured provider %s is not supported", config.GitProvider.Name) + } + envName := fmt.Sprintf("%s_ACCESS_TOKEN", strings.ToUpper(config.GitProvider.Name)) + + token, isSet := os.LookupEnv(envName) + if !isSet { + return ReleaseConfig{}, fmt.Errorf("config: Can not find environment variable %s", token) + } + config.GitProvider.AccessToken = token + } + return config, nil +} From ef60526644dce6353cfce942e531f12d9d380f3b Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 13 Jun 2019 19:37:55 +0200 Subject: [PATCH 20/77] chore(config/gitprovider): remove yaml description for accessToken --- .release.yml | 8 ++++---- pkg/config/config.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.release.yml b/.release.yml index eb9ed36..d0f9d33 100644 --- a/.release.yml +++ b/.release.yml @@ -12,7 +12,7 @@ release: 'github' assets: - name: compress: -github: - url: '' -gitlab: - url: '' +provider: + name: "" + url: "" + user: "" diff --git a/pkg/config/config.go b/pkg/config/config.go index b0a35f5..4259165 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -26,7 +26,7 @@ type GitProvider struct { Name string `yaml:"name"` URL string `yaml:"url"` User string `yaml:"user"` - AccessToken string `yaml:"accessToken"` + AccessToken string } type Asset struct { From edd1cbbfec1b1d930fac27ea214288da542526c6 Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 13 Jun 2019 19:47:04 +0200 Subject: [PATCH 21/77] chroe(config): fix go lint issues --- pkg/config/config.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/config/config.go b/pkg/config/config.go index 4259165..727522e 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -29,6 +29,7 @@ type GitProvider struct { AccessToken string } +//Asset type struct type Asset struct { Name string `yaml:"name"` Compress bool `yaml:"compress"` From c8a9f04f6b4add038fe1eb93e420195d610dd0e9 Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 13 Jun 2019 20:10:06 +0200 Subject: [PATCH 22/77] chore(config): add debug log --- pkg/config/config.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/config/config.go b/pkg/config/config.go index 727522e..eaf6cfe 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -81,6 +81,8 @@ func checkProvider(config ReleaseConfig) (ReleaseConfig, error) { return ReleaseConfig{}, fmt.Errorf("config: Can not find environment variable %s", token) } config.GitProvider.AccessToken = token + } else { + log.Debugln("No provider is set, will continue") } return config, nil } From 374548c45468e6bd9658e3cc3d94adf28147c449 Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 13 Jun 2019 21:45:55 +0200 Subject: [PATCH 23/77] chore(pkg/semantic-release/changelog): get URL parameter from release-config --- pkg/semanticrelease/semantic-release.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index 036182d..8cc0852 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -213,7 +213,7 @@ func (s *SemanticRelease) GetChangelog(repro, file string) error { result := a.Analyze(commits) c := changelog.New(s.config, a.GetRules()) - _, content, err := c.GenerateChanglog(nextVersion, "https://github.com/Nightapes/go-semantic-release/commit/{{hash}}", result) + _, content, err := c.GenerateChanglog(nextVersion, s.config.GitProvider.URL+"{{hash}}", result) if err != nil { return err } From cd362c63bd4cb57aeda1be872266b65e9e9f047c Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 13 Jun 2019 23:31:14 +0200 Subject: [PATCH 24/77] chore(config): add providers default domains, git providers can now specify a custom provider url for supported providers, add releaseTitle in config --- .release.yml | 6 ++++-- pkg/config/config.go | 25 ++++++++++++++++++------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/.release.yml b/.release.yml index d0f9d33..4d30862 100644 --- a/.release.yml +++ b/.release.yml @@ -1,4 +1,5 @@ commitFormat: angular +title: "testr release" branch: master: release rc: rc @@ -13,6 +14,7 @@ assets: - name: compress: provider: - name: "" - url: "" + name: "GitHub" + repo: "" user: "" + customURL: "" diff --git a/pkg/config/config.go b/pkg/config/config.go index eaf6cfe..f34afc9 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -12,7 +12,7 @@ import ( ) // List of all supported git providers -var gitPorviders = map[string]string{"GitHub": "", "GitLab": ""} +var gitProviders = map[string]string{"GitHub": "https://github.com/", "GitLab": "https://gitlab.com/"} // ChangelogConfig struct type ChangelogConfig struct { @@ -23,10 +23,11 @@ type ChangelogConfig struct { // GitProvider struct type GitProvider struct { - Name string `yaml:"name"` - URL string `yaml:"url"` - User string `yaml:"user"` - AccessToken string + Name string `yaml:"name"` + Repo string `yaml:"repo"` + User string `yaml:"user"` + customProviderURL string `yaml:"customURL"` + AccessToken string } //Asset type struct @@ -43,6 +44,7 @@ type ReleaseConfig struct { Release string `yaml:"release,omitempty"` GitProvider GitProvider `yaml:"provider,omitempty"` Assets []Asset `yaml:"assets"` + ReleaseTitle string `yaml:"title"` IsPreRelease, IsDraft bool } @@ -71,14 +73,14 @@ func Read(configPath string) (*ReleaseConfig, error) { func checkProvider(config ReleaseConfig) (ReleaseConfig, error) { if config.GitProvider != (GitProvider{}) { - if _, ok := gitPorviders[config.GitProvider.Name]; !ok { + if _, ok := gitProviders[config.GitProvider.Name]; !ok { return ReleaseConfig{}, fmt.Errorf("config: provider: configured provider %s is not supported", config.GitProvider.Name) } envName := fmt.Sprintf("%s_ACCESS_TOKEN", strings.ToUpper(config.GitProvider.Name)) token, isSet := os.LookupEnv(envName) if !isSet { - return ReleaseConfig{}, fmt.Errorf("config: Can not find environment variable %s", token) + return ReleaseConfig{}, fmt.Errorf("config: Can not find environment variable %s", envName) } config.GitProvider.AccessToken = token } else { @@ -86,3 +88,12 @@ func checkProvider(config ReleaseConfig) (ReleaseConfig, error) { } return config, nil } + +// GetRepositoryURL returns the repo FQDN +func (c *ReleaseConfig) GetRepositoryURL() string { + if c.GitProvider.customProviderURL == "" { + return fmt.Sprintf("%s/%s/%s/", c.GitProvider.customProviderURL, c.GitProvider.User, c.GitProvider.Repo) + } else { + return fmt.Sprintf("%s/%s/%s/", gitProviders[c.GitProvider.Name], c.GitProvider.User, c.GitProvider.Repo) + } +} From f8f6a3b2569d2490fa0211c0f4b5618304ef1a66 Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 13 Jun 2019 23:32:12 +0200 Subject: [PATCH 25/77] update(releaser/github): update github provider for previous changes in release config --- internal/releaser/github.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/releaser/github.go b/internal/releaser/github.go index 62197d7..64d2497 100644 --- a/internal/releaser/github.go +++ b/internal/releaser/github.go @@ -28,7 +28,7 @@ type gitHubCreateReleaseResponse struct { // NewGitHubReleaser initialize a new GitHubRelease func NewGitHubReleaser(c *config.ReleaseConfig) *GitHubReleaser { ctx := context.Background() - httpClient := createHTTPClient(ctx, c.Github.AccessToken) + httpClient := createHTTPClient(ctx, c.GitProvider.AccessToken) return &GitHubReleaser{ config: c, @@ -40,7 +40,7 @@ func NewGitHubReleaser(c *config.ReleaseConfig) *GitHubReleaser { // CreateRelease creates release on remote func (g GitHubReleaser) CreateRelease(tag, releaseName, releaseMessage, targetBranch string) error { - release, resp, err := g.client.Repositories.CreateRelease(g.context, g.config.Github.User, g.config.Github.URL, &github.RepositoryRelease{ + release, resp, err := g.client.Repositories.CreateRelease(g.context, g.config.GitProvider.User, g.config.GitProvider.Repo, &github.RepositoryRelease{ TagName: &tag, TargetCommitish: &targetBranch, Name: &releaseName, @@ -70,7 +70,7 @@ func (g GitHubReleaser) UploadAssets(assets []config.Asset) error { return err } - _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.Github.User, g.config.Github.URL, *g.release.ID, &github.UploadOptions{Name: asset.Name}, file) + _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.GitProvider.User, g.config.GitProvider.Repo, *g.release.ID, &github.UploadOptions{Name: asset.Name}, file) if err != nil { return err } From cdf3d15105f41eb0f15827bc9b9c05414fdd78f2 Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 13 Jun 2019 23:33:42 +0200 Subject: [PATCH 26/77] ref(pkg/semantic-release): add wrapper method for writing changelog, add method for make a new release --- cmd/go-semantic-release/main.go | 11 +++++- pkg/semanticrelease/semantic-release.go | 51 +++++++++++++++++++++---- 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/cmd/go-semantic-release/main.go b/cmd/go-semantic-release/main.go index d7cfd3a..5f5ef94 100644 --- a/cmd/go-semantic-release/main.go +++ b/cmd/go-semantic-release/main.go @@ -43,6 +43,9 @@ func main() { log.Fatal(err) } fmt.Println(version) + if err = s.Release(*nextRepository); err != nil { + log.Fatal(err) + } case setCommand.FullCommand(): setLoglevel(*loglevel) @@ -52,13 +55,19 @@ func main() { if err != nil { log.Fatal(err) } + if err = s.Release(*setRepository); err != nil { + log.Fatal(err) + } case getChangelog.FullCommand(): setLoglevel(*loglevel) s := semanticrelease.New(readConfig(getChangelogConfigPath)) - err := s.GetChangelog(*getChangelogRepository, *getChangelogFile) + changelog, err := s.GetChangelog(*getChangelogRepository) if err != nil { log.Fatal(err) } + if err = s.WriteChangeLog(changelog, *getChangelogFile); err != nil { + log.Fatal(err) + } } } diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index 8cc0852..2cb7c95 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -2,6 +2,7 @@ package semanticrelease import ( + "fmt" "io/ioutil" "strconv" "strings" @@ -11,6 +12,7 @@ import ( "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/releaser" "github.com/Nightapes/go-semantic-release/pkg/config" log "github.com/sirupsen/logrus" ) @@ -182,41 +184,74 @@ func incPrerelease(preReleaseType string, version semver.Version) semver.Version } // GetChangelog from last version till now -func (s *SemanticRelease) GetChangelog(repro, file string) error { +func (s *SemanticRelease) GetChangelog(repro string) (string, error) { nextVersion, err := s.GetNextVersion(repro, false) if err != nil { log.Debugf("Could not get next version") - return err + return "", err } util, err := gitutil.New(repro) if err != nil { - return err + return "", err } _, lastVersionHash, err := util.GetLastVersion() if err != nil { - return err + return "", err } commits, err := util.GetCommits(lastVersionHash) if err != nil { - return err + return "", err } log.Debugf("Found %d commits till last release", len(commits)) a, err := analyzer.New(s.config.CommitFormat, s.config.Changelog) if err != nil { - return err + return "", err } result := a.Analyze(commits) c := changelog.New(s.config, a.GetRules()) - _, content, err := c.GenerateChanglog(nextVersion, s.config.GitProvider.URL+"{{hash}}", result) + _, content, err := c.GenerateChanglog(nextVersion, s.config.GetRepositoryURL()+"{{hash}}", result) + if err != nil { + return "", err + } + return content, nil + +} + +// WriteChangeLog wirtes changelog content to the given file +func (s *SemanticRelease) WriteChangeLog(changelogContent, file string) error { + return ioutil.WriteFile(file, []byte(changelogContent), 0644) +} + +// Release pusblish release to provider +func (s *SemanticRelease) Release(repo string) error { + nextVersion, err := s.GetNextVersion(repo, false) + if err != nil { + log.Debugf("Could not get next version") + return err + } + + changelog, err := s.GetChangelog(repo) + if err != nil { + log.Debugf("Could not get changelog") + return err + } + + releaseTitle := fmt.Sprintf("%s v%s", s.config.ReleaseTitle, nextVersion) + + releaser, err := releaser.New(s.config).GetReleaser() if err != nil { return err } - return ioutil.WriteFile(file, []byte(content), 0644) + if err = releaser.CreateRelease(nextVersion, releaseTitle, changelog, "master"); err != nil { + return err + } + + return nil } From ead86a769adb0237b41a987ded7edbbb0c2e8f88 Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 13 Jun 2019 23:45:21 +0200 Subject: [PATCH 27/77] chore(pkg/semantic-releaser): check if current branch is configured for releases --- pkg/semanticrelease/semantic-release.go | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index 2cb7c95..ddb0008 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -30,8 +30,8 @@ func New(c *config.ReleaseConfig) *SemanticRelease { } // GetNextVersion from .version or calculate new from commits -func (s *SemanticRelease) GetNextVersion(repro string, force bool) (string, error) { - util, err := gitutil.New(repro) +func (s *SemanticRelease) GetNextVersion(repo string, force bool) (string, error) { + util, err := gitutil.New(repo) if err != nil { return "", err } @@ -114,9 +114,9 @@ func (s *SemanticRelease) GetNextVersion(repro string, force bool) (string, erro } //SetVersion for git repository -func (s *SemanticRelease) SetVersion(version string, repro string) error { +func (s *SemanticRelease) SetVersion(version string, repo string) error { - util, err := gitutil.New(repro) + util, err := gitutil.New(repo) if err != nil { return err } @@ -184,14 +184,14 @@ func incPrerelease(preReleaseType string, version semver.Version) semver.Version } // GetChangelog from last version till now -func (s *SemanticRelease) GetChangelog(repro string) (string, error) { - nextVersion, err := s.GetNextVersion(repro, false) +func (s *SemanticRelease) GetChangelog(repo string) (string, error) { + nextVersion, err := s.GetNextVersion(repo, false) if err != nil { log.Debugf("Could not get next version") return "", err } - util, err := gitutil.New(repro) + util, err := gitutil.New(repo) if err != nil { return "", err } @@ -230,6 +230,17 @@ func (s *SemanticRelease) WriteChangeLog(changelogContent, file string) error { // Release pusblish release to provider func (s *SemanticRelease) Release(repo string) error { + util, err := gitutil.New(repo) + if err != nil { + return err + } + currentBranch, err := util.GetBranch() + + if _, ok := s.config.Branch[currentBranch]; !ok { + log.Debugf("Will not perform a new release. Current %s branch is not configured in release config", currentBranch) + return nil + } + nextVersion, err := s.GetNextVersion(repo, false) if err != nil { log.Debugf("Could not get next version") From 27ddd1872b20e430a98932b3ab548978d544d646 Mon Sep 17 00:00:00 2001 From: fwiedmann Date: Fri, 14 Jun 2019 09:40:26 +0200 Subject: [PATCH 28/77] chore(pkg/semantic-release): remove unused method call --- pkg/semanticrelease/semantic-release.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index ddb0008..c92a020 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -107,9 +107,6 @@ func (s *SemanticRelease) GetNextVersion(repo string, force bool) (string, error if err != nil { return "", err } - c := changelog.New(s.config, a.GetRules()) - c.GenerateChanglog(newVersion.String(), "https://github.com/Nightapes/go-semantic-release/commit/{{hash}}", result) - return newVersion.String(), err } @@ -215,7 +212,7 @@ func (s *SemanticRelease) GetChangelog(repo string) (string, error) { result := a.Analyze(commits) c := changelog.New(s.config, a.GetRules()) - _, content, err := c.GenerateChanglog(nextVersion, s.config.GetRepositoryURL()+"{{hash}}", result) + _, content, err := c.GenerateChanglog(nextVersion, s.config.GetRepositoryURL()+"/commit/{{hash}}", result) if err != nil { return "", err } From 1bc7f4bc677582818350b462940d9dff2c9ac72d Mon Sep 17 00:00:00 2001 From: fwiedmann Date: Fri, 14 Jun 2019 09:41:14 +0200 Subject: [PATCH 29/77] chore(pkg/config): change if expression --- pkg/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index f34afc9..f06b0e2 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -91,7 +91,7 @@ func checkProvider(config ReleaseConfig) (ReleaseConfig, error) { // GetRepositoryURL returns the repo FQDN func (c *ReleaseConfig) GetRepositoryURL() string { - if c.GitProvider.customProviderURL == "" { + if c.GitProvider.customProviderURL != "" { return fmt.Sprintf("%s/%s/%s/", c.GitProvider.customProviderURL, c.GitProvider.User, c.GitProvider.Repo) } else { return fmt.Sprintf("%s/%s/%s/", gitProviders[c.GitProvider.Name], c.GitProvider.User, c.GitProvider.Repo) From cf0431846b33139881678b2cf566057279c786f9 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Sat, 15 Jun 2019 23:03:27 +0200 Subject: [PATCH 30/77] refactor(*): clean up code --- .release.yml | 10 +- cmd/go-semantic-release/main.go | 86 +-------- go.mod | 16 +- go.sum | 81 +++++++- internal/cache/cache.go | 33 ++-- internal/changelog/changelog.go | 13 +- internal/gitutil/gitutil.go | 2 +- internal/releaser/github.go | 83 -------- internal/releaser/github/github.go | 128 +++++++++++++ internal/releaser/releaser.go | 34 ++-- internal/releaser/util/util.go | 19 ++ internal/shared/shared.go | 32 ++++ pkg/config/config.go | 56 +----- pkg/semanticrelease/helper.go | 87 +++++++++ pkg/semanticrelease/semantic-release.go | 242 +++++++++++------------- 15 files changed, 517 insertions(+), 405 deletions(-) delete mode 100644 internal/releaser/github.go create mode 100644 internal/releaser/github/github.go create mode 100644 internal/releaser/util/util.go create mode 100644 internal/shared/shared.go create mode 100644 pkg/semanticrelease/helper.go diff --git a/.release.yml b/.release.yml index 4d30862..c26bd48 100644 --- a/.release.yml +++ b/.release.yml @@ -5,6 +5,7 @@ branch: rc: rc beta: beta alpha: alpha + add_git_releases: alpha changelog: printAll: false template: '' @@ -13,8 +14,7 @@ release: 'github' assets: - name: compress: -provider: - name: "GitHub" - repo: "" - user: "" - customURL: "" +github: + repo: "go-semantic-release" + user: "nightapes" + customUrl: "" diff --git a/cmd/go-semantic-release/main.go b/cmd/go-semantic-release/main.go index 5f5ef94..a31920a 100644 --- a/cmd/go-semantic-release/main.go +++ b/cmd/go-semantic-release/main.go @@ -1,91 +1,9 @@ -// Package main as start point for go build package main import ( - "fmt" - "os" - - "github.com/Nightapes/go-semantic-release/pkg/config" - "github.com/Nightapes/go-semantic-release/pkg/semanticrelease" - - log "github.com/sirupsen/logrus" - "gopkg.in/alecthomas/kingpin.v2" -) - -var ( - app = kingpin.New("go-semantic-release", "A command-line for releasing software") - loglevel = app.Flag("loglevel", "Set loglevel.").Default("error").HintOptions("error", "warning", "info", "debug").Short('l').String() - - nextCommand = app.Command("next", "Print next version") - nextRepository = nextCommand.Flag("repository", "Path to repository").String() - nextConfigPath = nextCommand.Flag("config", "Path to config file").Default(".release.yml").String() - nextForce = nextCommand.Flag("force", "Ignore cache, don't use in ci build").Bool() - - setCommand = app.Command("set", "Set version for current build.") - setRepository = setCommand.Flag("repository", "Path to repository").String() - setConfigPath = setCommand.Flag("config", "Path to config file").Default(".release.yml").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() + "github.com/Nightapes/go-semantic-release/cmd/go-semantic-release/commands" ) func main() { - - switch kingpin.MustParse(app.Parse(os.Args[1:])) { - case nextCommand.FullCommand(): - setLoglevel(*loglevel) - s := semanticrelease.New(readConfig(nextConfigPath)) - version, err := s.GetNextVersion(*nextRepository, *nextForce) - if err != nil { - log.Fatal(err) - } - fmt.Println(version) - if err = s.Release(*nextRepository); err != nil { - log.Fatal(err) - } - - case setCommand.FullCommand(): - setLoglevel(*loglevel) - log.Infof("Version %s", *setVersion) - s := semanticrelease.New(readConfig(setConfigPath)) - err := s.SetVersion(*setVersion, *setRepository) - if err != nil { - log.Fatal(err) - } - if err = s.Release(*setRepository); err != nil { - log.Fatal(err) - } - case getChangelog.FullCommand(): - setLoglevel(*loglevel) - s := semanticrelease.New(readConfig(getChangelogConfigPath)) - changelog, err := s.GetChangelog(*getChangelogRepository) - if err != nil { - log.Fatal(err) - } - if err = s.WriteChangeLog(changelog, *getChangelogFile); err != nil { - log.Fatal(err) - } - } - -} - -func readConfig(path *string) *config.ReleaseConfig { - releaseConfig, err := config.Read(*path) - if err != nil { - log.Fatal(err) - } - return releaseConfig -} - -func setLoglevel(level string) { - parsed, err := log.ParseLevel(level) - if err != nil { - log.Errorf("Invalid loglevel %s", level) - } else { - log.SetLevel(parsed) - } - + commands.Execute() } diff --git a/go.mod b/go.mod index 9a92235..eff09c3 100644 --- a/go.mod +++ b/go.mod @@ -4,12 +4,18 @@ go 1.12 require ( github.com/Masterminds/semver v1.4.2 - github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect - github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect + github.com/google/go-cmp v0.3.0 // indirect github.com/google/go-github/v25 v25.1.1 - github.com/sirupsen/logrus v1.4.1 - golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be - gopkg.in/alecthomas/kingpin.v2 v2.2.6 + github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect + github.com/pkg/errors v0.8.1 // indirect + github.com/sirupsen/logrus v1.4.2 + github.com/spf13/cobra v0.0.5 + github.com/stretchr/testify v1.3.0 // indirect + golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 // indirect + golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 // indirect + golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 + golang.org/x/sys v0.0.0-20190614160838-b47fdc937951 // indirect + google.golang.org/appengine v1.6.1 // indirect gopkg.in/src-d/go-git.v4 v4.11.0 gopkg.in/yaml.v2 v2.2.2 ) diff --git a/go.sum b/go.sum index 39e2eec..7ea57ff 100644 --- a/go.sum +++ b/go.sum @@ -1,29 +1,43 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emirpasic/gods v1.9.0 h1:rUF4PuzEjMChMiNsVjdI+SyLu7rEqpQ5reNFnhC7oFo= github.com/emirpasic/gods v1.9.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-github/v25 v25.1.1 h1:6eW++i/CXcR5GKfYaaJT7oJJtHNU+/iiw55noEPNVao= github.com/google/go-github/v25 v25.1.1/go.mod h1:6z5pC69qHtrPJ0sXPsj4BLnd82b+r6sLB7qcBoRZqpw= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -31,53 +45,102 @@ github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e h1:RgQk53JHp github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA= github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xanzy/ssh-agent v0.2.0 h1:Adglfbi5p9Z0BmK2oKU9nTG+zKfniSfnaMYB+ULd+Ro= github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9 h1:lkiLiLBHGoH3XnqSLUIaBsilGMUjI+Uy2Xu2JLUtTas= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190614160838-b47fdc937951 h1:ZUgGZ7PSkne6oY+VgAvayrB16owfm9/DKAtgWubzgzU= +golang.org/x/sys v0.0.0-20190614160838-b47fdc937951/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/cache/cache.go b/internal/cache/cache.go index e64a061..cb03426 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -3,40 +3,49 @@ package cache import ( "io/ioutil" + "path" "gopkg.in/yaml.v2" ) // VersionFileContent struct -type VersionFileContent struct { - Version string `yaml:"version"` - NextVersion string `yaml:"nextVersion"` - Commit string `yaml:"commit"` - Branch string `yaml:"branch"` +type ReleaseVersion struct { + Last ReleaseVersionEntry `yaml:"last"` + Next ReleaseVersionEntry `yaml:"next"` + Branch string `yaml:"branch"` +} + +//VersionFileEntry struct +type ReleaseVersionEntry struct { + Commit string `yaml:"commit"` + Version string `yaml:"version"` } // Write version into .version -func Write(versionFileContent VersionFileContent) error { +func Write(repository string, versionFileContent ReleaseVersion) error { + completePath := path.Join(path.Dir(repository), ".version") + data, err := yaml.Marshal(&versionFileContent) if err != nil { return err } - return ioutil.WriteFile(".version", data, 0644) + return ioutil.WriteFile(completePath, data, 0644) } // Read version into .version -func Read() (*VersionFileContent, error) { +func Read(repository string) (*ReleaseVersion, error) { + completePath := path.Join(path.Dir(repository), ".version") - content, err := ioutil.ReadFile(".version") + content, err := ioutil.ReadFile(completePath) if err != nil { - return &VersionFileContent{}, err + return &ReleaseVersion{}, err } - var versionFileContent VersionFileContent + var versionFileContent ReleaseVersion err = yaml.Unmarshal(content, &versionFileContent) if err != nil { - return &VersionFileContent{}, err + return &ReleaseVersion{}, err } return &versionFileContent, nil diff --git a/internal/changelog/changelog.go b/internal/changelog/changelog.go index eed9d11..f1a9319 100644 --- a/internal/changelog/changelog.go +++ b/internal/changelog/changelog.go @@ -7,6 +7,7 @@ import ( "time" "github.com/Nightapes/go-semantic-release/internal/analyzer" + "github.com/Nightapes/go-semantic-release/internal/shared" "github.com/Nightapes/go-semantic-release/pkg/config" log "github.com/sirupsen/logrus" @@ -49,7 +50,7 @@ func New(config *config.ReleaseConfig, rules []analyzer.Rule) *Changelog { } // GenerateChanglog from given commits -func (c *Changelog) GenerateChanglog(version, url string, analyzedCommits map[string][]analyzer.AnalyzedCommit) (string, string, error) { +func (c *Changelog) GenerateChanglog(templateConfig shared.ChangelogTemplateConfig, analyzedCommits map[string][]analyzer.AnalyzedCommit) (*shared.GeneratedChangelog, error) { commitsPerScope := map[string][]analyzer.AnalyzedCommit{} order := make([]string, 0) @@ -73,22 +74,22 @@ func (c *Changelog) GenerateChanglog(version, url string, analyzedCommits map[st } changelogContent := changelogContent{ - Version: version, + Version: templateConfig.Version, Commits: commitsPerScope, Now: time.Now(), Backtick: "`", Order: order, - HasURL: url != "", - URL: url, + HasURL: templateConfig.CommitURL != "", + URL: templateConfig.CommitURL, } title, err := generateTemplate(defaultChangelogTitle, changelogContent) if err != nil { - return "", "", err + return nil, err } content, err := generateTemplate(defaultChangelog, changelogContent) - return title, content, err + return &shared.GeneratedChangelog{Title: title, Content: content}, err } func generateTemplate(text string, values changelogContent) (string, error) { diff --git a/internal/gitutil/gitutil.go b/internal/gitutil/gitutil.go index 028d35a..a721f4c 100644 --- a/internal/gitutil/gitutil.go +++ b/internal/gitutil/gitutil.go @@ -136,7 +136,7 @@ func (g *GitUtil) GetCommits(lastTagHash string) ([]Commit, error) { log.Debugf("Found commit with hash %s, will stop here", c.Hash.String()) foundEnd = true } - + log.Tracef("Found commit with hash %s", c.Hash.String()) if !foundEnd { commit := Commit{ Message: c.Message, diff --git a/internal/releaser/github.go b/internal/releaser/github.go deleted file mode 100644 index 64d2497..0000000 --- a/internal/releaser/github.go +++ /dev/null @@ -1,83 +0,0 @@ -package releaser - -import ( - "context" - "fmt" - "github.com/Nightapes/go-semantic-release/pkg/config" - "github.com/google/go-github/v25/github" - "net/http" - "os" -) - -// GITHUB identifer for github interface -const GITHUB = "GitHub" - -// GitHubReleaser type struct -type GitHubReleaser struct { - config *config.ReleaseConfig - client *github.Client - context context.Context - release *github.RepositoryRelease -} - -type gitHubCreateReleaseResponse struct { - ReleaseURL string `json:url` - AssetUploadURL string `json:upload_url` -} - -// NewGitHubReleaser initialize a new GitHubRelease -func NewGitHubReleaser(c *config.ReleaseConfig) *GitHubReleaser { - ctx := context.Background() - httpClient := createHTTPClient(ctx, c.GitProvider.AccessToken) - - return &GitHubReleaser{ - config: c, - client: github.NewClient(httpClient), - context: ctx, - } -} - -// CreateRelease creates release on remote -func (g GitHubReleaser) CreateRelease(tag, releaseName, releaseMessage, targetBranch string) error { - - release, resp, err := g.client.Repositories.CreateRelease(g.context, g.config.GitProvider.User, g.config.GitProvider.Repo, &github.RepositoryRelease{ - TagName: &tag, - TargetCommitish: &targetBranch, - Name: &releaseName, - Body: &releaseMessage, - Draft: &g.config.IsDraft, - Prerelease: &g.config.IsPreRelease, - }) - - if err != nil { - return fmt.Errorf("releaser: github: Could not create release: %v", err) - } - - if resp.StatusCode >= http.StatusBadRequest { - return fmt.Errorf("releaser: github: Could not create release: response statuscode: %s", resp.Status) - } - - g.release = release - return nil - -} - -// UploadAssets uploads specified assets -func (g GitHubReleaser) UploadAssets(assets []config.Asset) error { - for _, asset := range assets { - file, err := os.Open(asset.Name) - if err != nil { - return err - } - - _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.GitProvider.User, g.config.GitProvider.Repo, *g.release.ID, &github.UploadOptions{Name: asset.Name}, file) - if err != nil { - return err - } - - if resp.StatusCode >= http.StatusBadRequest { - return fmt.Errorf("releaser: github: Could not create release: response statuscode: %s", resp.Status) - } - } - return nil -} diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go new file mode 100644 index 0000000..f9b9484 --- /dev/null +++ b/internal/releaser/github/github.go @@ -0,0 +1,128 @@ +package github + +import ( + "context" + "fmt" + "net/http" + "os" + "strings" + + "github.com/Nightapes/go-semantic-release/internal/releaser/util" + "github.com/Nightapes/go-semantic-release/internal/shared" + "github.com/Nightapes/go-semantic-release/pkg/config" + + "github.com/google/go-github/v25/github" +) + +// GITHUB identifer for github interface +const GITHUB = "github" + +// GitHubReleaser type struct +type GitHubReleaser struct { + config *config.GitHubProvider + client *github.Client + context context.Context + release *github.RepositoryRelease + baseURL string + token string +} + +// New initialize a new GitHubRelease +func New(c *config.GitHubProvider) (*GitHubReleaser, error) { + ctx := context.Background() + httpClient := util.CreateBearerHTTPClient(ctx, c.AccessToken) + + var client *github.Client + var err error + baseURL := "https://github.com" + if c.CustomURL == "" { + client = github.NewClient(httpClient) + } else { + client, err = github.NewEnterpriseClient(c.CustomURL, c.CustomURL+"/api/v3/", httpClient) + baseURL = c.CustomURL + } + return &GitHubReleaser{ + config: c, + client: client, + context: ctx, + baseURL: baseURL, + }, err +} + +//GetCommitURL for github +func (g GitHubReleaser) GetCommitURL() string { + return fmt.Sprintf("%s/%s/%s/commit/{{hash}}", g.baseURL, g.config.User, g.config.Repo) +} + +//GetCompareURL for github +func (g GitHubReleaser) GetCompareURL(oldVersion, newVersion string) string { + return fmt.Sprintf("%s/%s/%s/compare/%s...%s", g.baseURL, g.config.User, g.config.Repo, oldVersion, newVersion) +} + +//ValidateConfig for github +func (g GitHubReleaser) ValidateConfig() error { + + if g.config.Repo == "" { + return fmt.Errorf("Github Repro is not set") + } + + if g.config.User == "" { + return fmt.Errorf("Github User is not set") + } + + envName := fmt.Sprintf("%s_ACCESS_TOKEN", strings.ToUpper(GITHUB)) + token, isSet := os.LookupEnv(envName) + if !isSet { + return fmt.Errorf("Can not find environment variable %s", envName) + } + g.token = token + return nil + +} + +// CreateRelease creates release on remote +func (g GitHubReleaser) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error { + + tag := releaseVersion.Next.Version.String() + prerelease := releaseVersion.Next.Version.Prerelease() != "" + release, resp, err := g.client.Repositories.CreateRelease(g.context, g.config.User, g.config.Repo, &github.RepositoryRelease{ + TagName: &tag, + TargetCommitish: &releaseVersion.Branch, + Name: &generatedChangelog.Title, + Body: &generatedChangelog.Content, + Draft: &prerelease, + Prerelease: &prerelease, + }) + + if err != nil { + return fmt.Errorf("Could not create release: %v", err) + } + + if resp.StatusCode >= http.StatusBadRequest { + return fmt.Errorf("Could not create release: response statuscode: %s", resp.Status) + } + + g.release = release + return nil + +} + +// UploadAssets uploads specified assets +func (g GitHubReleaser) UploadAssets(assets []config.Asset) error { + for _, asset := range assets { + file, err := os.Open(asset.Name) + if err != nil { + return err + } + + _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.User, g.config.Repo, *g.release.ID, &github.UploadOptions{Name: asset.Name}, file) + if err != nil { + return err + } + + if resp.StatusCode >= http.StatusBadRequest { + return fmt.Errorf("releaser: github: Could not create release: response statuscode: %s", resp.Status) + } + } + return nil +} diff --git a/internal/releaser/releaser.go b/internal/releaser/releaser.go index 3e095bb..6970fe2 100644 --- a/internal/releaser/releaser.go +++ b/internal/releaser/releaser.go @@ -1,12 +1,13 @@ package releaser import ( - "context" "fmt" - "github.com/Nightapes/go-semantic-release/pkg/config" - "golang.org/x/oauth2" - "net/http" "os" + + "github.com/Nightapes/go-semantic-release/internal/releaser/github" + "github.com/Nightapes/go-semantic-release/internal/shared" + + "github.com/Nightapes/go-semantic-release/pkg/config" ) // Releasers struct type @@ -16,8 +17,11 @@ type Releasers struct { // Releaser interface for providers type Releaser interface { - CreateRelease(tag, releaseName, releaseMessage, targetBranch string) error + ValidateConfig() error + CreateRelease(*shared.ReleaseVersion, *shared.GeneratedChangelog) error UploadAssets(assets []config.Asset) error + GetCommitURL() string + GetCompareURL(oldVersion, newVersion string) string } // New initialize a Relerser @@ -29,23 +33,11 @@ func New(c *config.ReleaseConfig) *Releasers { //GetReleaser returns an initialized releaser func (r *Releasers) GetReleaser() (Releaser, error) { - switch r.config.GitProvider.Name { - case GITHUB: - return NewGitHubReleaser(r.config), nil + switch r.config.Release { + case github.GITHUB: + return github.New(&r.config.GitHubProvider) } - return nil, fmt.Errorf("Could not initialize a releaser from this type: %s", r.config.GitProvider.Name) -} - -// tbd. http helper function - -func createHTTPClient(ctx context.Context, token string) *http.Client { - tokenSource := oauth2.StaticTokenSource(&oauth2.Token{ - AccessToken: token}, - ) - - client := oauth2.NewClient(ctx, tokenSource) - - return client + return nil, fmt.Errorf("Could not initialize a releaser from this type: %s", r.config.Release) } func checkIfAssetsExists(assets []config.Asset) error { diff --git a/internal/releaser/util/util.go b/internal/releaser/util/util.go new file mode 100644 index 0000000..6479ace --- /dev/null +++ b/internal/releaser/util/util.go @@ -0,0 +1,19 @@ +package util + +import ( + "context" + "net/http" + + "golang.org/x/oauth2" +) + +//CreateBearerHTTPClient with given token +func CreateBearerHTTPClient(ctx context.Context, token string) *http.Client { + tokenSource := oauth2.StaticTokenSource(&oauth2.Token{ + AccessToken: token}, + ) + + client := oauth2.NewClient(ctx, tokenSource) + + return client +} diff --git a/internal/shared/shared.go b/internal/shared/shared.go new file mode 100644 index 0000000..3d0154a --- /dev/null +++ b/internal/shared/shared.go @@ -0,0 +1,32 @@ +package shared + +import ( + "github.com/Masterminds/semver" +) + +//ReleaseVersion struct +type ReleaseVersion struct { + Last ReleaseVersionEntry + Next ReleaseVersionEntry + Branch string +} + +//ReleaseVersionEntry struct +type ReleaseVersionEntry struct { + Commit string + Version *semver.Version +} + +//GeneratedChangelog struct +type GeneratedChangelog struct { + Title string + Content string +} + +//GenerateChangelogConfig struct +type ChangelogTemplateConfig struct { + CommitURL string + CompareURL string + Hash string + Version string +} diff --git a/pkg/config/config.go b/pkg/config/config.go index f06b0e2..62a2a4d 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -2,18 +2,12 @@ package config import ( - "fmt" "io/ioutil" - "os" - "strings" log "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" ) -// List of all supported git providers -var gitProviders = map[string]string{"GitHub": "https://github.com/", "GitLab": "https://gitlab.com/"} - // ChangelogConfig struct type ChangelogConfig struct { PrintAll bool `yaml:"printAll,omitempty"` @@ -21,28 +15,27 @@ type ChangelogConfig struct { TemplatePath string `yaml:"templatePath,omitempty"` } -// GitProvider struct -type GitProvider struct { - Name string `yaml:"name"` - Repo string `yaml:"repo"` - User string `yaml:"user"` - customProviderURL string `yaml:"customURL"` - AccessToken string -} - //Asset type struct type Asset struct { Name string `yaml:"name"` Compress bool `yaml:"compress"` } +// GitHubProvider struct +type GitHubProvider struct { + Repo string `yaml:"repo"` + User string `yaml:"user"` + CustomURL string `yaml:"customUrl,omitempty"` + AccessToken string +} + // ReleaseConfig struct type ReleaseConfig struct { CommitFormat string `yaml:"commitFormat"` Branch map[string]string `yaml:"branch"` Changelog ChangelogConfig `yaml:"changelog,omitempty"` Release string `yaml:"release,omitempty"` - GitProvider GitProvider `yaml:"provider,omitempty"` + GitHubProvider GitHubProvider `yaml:"github,omitempty"` Assets []Asset `yaml:"assets"` ReleaseTitle string `yaml:"title"` IsPreRelease, IsDraft bool @@ -64,36 +57,5 @@ func Read(configPath string) (*ReleaseConfig, error) { log.Debugf("Found config %+v", releaseConfig) - releaseConfig, err = checkProvider(releaseConfig) - if err != nil { - return &ReleaseConfig{}, err - } return &releaseConfig, nil } - -func checkProvider(config ReleaseConfig) (ReleaseConfig, error) { - if config.GitProvider != (GitProvider{}) { - if _, ok := gitProviders[config.GitProvider.Name]; !ok { - return ReleaseConfig{}, fmt.Errorf("config: provider: configured provider %s is not supported", config.GitProvider.Name) - } - envName := fmt.Sprintf("%s_ACCESS_TOKEN", strings.ToUpper(config.GitProvider.Name)) - - token, isSet := os.LookupEnv(envName) - if !isSet { - return ReleaseConfig{}, fmt.Errorf("config: Can not find environment variable %s", envName) - } - config.GitProvider.AccessToken = token - } else { - log.Debugln("No provider is set, will continue") - } - return config, nil -} - -// GetRepositoryURL returns the repo FQDN -func (c *ReleaseConfig) GetRepositoryURL() string { - if c.GitProvider.customProviderURL != "" { - return fmt.Sprintf("%s/%s/%s/", c.GitProvider.customProviderURL, c.GitProvider.User, c.GitProvider.Repo) - } else { - return fmt.Sprintf("%s/%s/%s/", gitProviders[c.GitProvider.Name], c.GitProvider.User, c.GitProvider.Repo) - } -} diff --git a/pkg/semanticrelease/helper.go b/pkg/semanticrelease/helper.go new file mode 100644 index 0000000..990f57e --- /dev/null +++ b/pkg/semanticrelease/helper.go @@ -0,0 +1,87 @@ +package semanticrelease + +import ( + "strconv" + "strings" + + "github.com/Masterminds/semver" + "github.com/Nightapes/go-semantic-release/internal/cache" + "github.com/Nightapes/go-semantic-release/internal/shared" + log "github.com/sirupsen/logrus" +) + +func (s *SemanticRelease) 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 +} + +func (s *SemanticRelease) saveToCache(releaseVersion shared.ReleaseVersion) error { + + toCache := cache.ReleaseVersion{ + Next: cache.ReleaseVersionEntry{ + Commit: releaseVersion.Next.Commit, + Version: releaseVersion.Next.Version.String(), + }, + Last: cache.ReleaseVersionEntry{ + Commit: releaseVersion.Last.Commit, + Version: releaseVersion.Last.Version.String(), + }, + Branch: releaseVersion.Branch, + } + + log.Debugf("Save %s with hash %s to cache", releaseVersion.Next.Version.String(), releaseVersion.Next.Commit) + return cache.Write(s.repository, toCache) +} + +func (s *SemanticRelease) readFromCache(currentHash string) (*shared.ReleaseVersion, error) { + content, err := cache.Read(s.repository) + + if err == nil && content.Next.Commit == currentHash { + + nextVersion, err := semver.NewVersion(content.Next.Version) + if err != nil { + return nil, err + } + + lastVersion, err := semver.NewVersion(content.Last.Version) + if err != nil { + return nil, err + } + + releaseVersion := &shared.ReleaseVersion{ + Next: shared.ReleaseVersionEntry{ + Commit: content.Next.Commit, + Version: nextVersion, + }, + Last: shared.ReleaseVersionEntry{ + Commit: content.Last.Commit, + Version: lastVersion, + }, + Branch: content.Branch, + } + + log.Infof("Found cache, will return cached version %s", content.Next.Version) + return releaseVersion, nil + + } + log.Debugf("Mismatch git and version file %s - %s", content.Next.Commit, currentHash) + return nil, nil +} diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index c92a020..61fca64 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -1,61 +1,83 @@ -// Package semanticrelease provides public methods to include in own code package semanticrelease import ( - "fmt" "io/ioutil" - "strconv" "strings" "github.com/Masterminds/semver" "github.com/Nightapes/go-semantic-release/internal/analyzer" - "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/releaser" + "github.com/Nightapes/go-semantic-release/internal/shared" "github.com/Nightapes/go-semantic-release/pkg/config" log "github.com/sirupsen/logrus" ) // SemanticRelease struct type SemanticRelease struct { - config *config.ReleaseConfig + config *config.ReleaseConfig + gitutil *gitutil.GitUtil + analyzer *analyzer.Analyzer + releaser releaser.Releaser + repository string } // New SemanticRelease struct -func New(c *config.ReleaseConfig) *SemanticRelease { - return &SemanticRelease{ - config: c, +func New(c *config.ReleaseConfig, repository string) (*SemanticRelease, error) { + util, err := gitutil.New(repository) + if err != nil { + return nil, err } + + analyzer, err := analyzer.New(c.CommitFormat, c.Changelog) + if err != nil { + return nil, err + } + + releaser, err := releaser.New(c).GetReleaser() + if err != nil { + return nil, err + } + + return &SemanticRelease{ + config: c, + gitutil: util, + releaser: releaser, + analyzer: analyzer, + repository: repository, + }, nil } // GetNextVersion from .version or calculate new from commits -func (s *SemanticRelease) GetNextVersion(repo string, force bool) (string, error) { - util, err := gitutil.New(repo) +func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, error) { + hash, err := s.gitutil.GetHash() if err != nil { - return "", err - } - - hash, err := util.GetHash() - if err != nil { - return "", err + return nil, err } log.Debugf("Ignore .version file if exits, %t", force) if !force { - content, err := cache.Read() - - if err == nil && content.Commit == hash { - log.Infof("Found cache, will return cached version %s", content.NextVersion) - return content.NextVersion, err + releaseVersion, err := s.readFromCache(hash) + if err != nil { + return nil, err + } + + if releaseVersion != nil { + return releaseVersion, nil } - log.Debugf("Mismatch git and version file %s - %s", content.Commit, hash) } - lastVersion, lastVersionHash, err := util.GetLastVersion() + currentBranch, err := s.gitutil.GetBranch() if err != nil { - return "", err + return nil, err } + + lastVersion, lastVersionHash, err := s.gitutil.GetLastVersion() + if err != nil { + return nil, err + } + var newVersion semver.Version if lastVersion == nil { @@ -66,30 +88,25 @@ func (s *SemanticRelease) GetNextVersion(repo string, force bool) (string, error newVersion = *lastVersion } - commits, err := util.GetCommits(lastVersionHash) + commits, err := s.gitutil.GetCommits(lastVersionHash) if err != nil { - return "", err + return nil, err } log.Debugf("Found %d commits till last release", len(commits)) a, err := analyzer.New(s.config.CommitFormat, s.config.Changelog) if err != nil { - return "", err + return nil, err } result := a.Analyze(commits) - currentBranch, err := util.GetBranch() - if err != nil { - return "", err - } - for branch, releaseType := range s.config.Branch { if currentBranch == branch || strings.HasPrefix(currentBranch, branch) { log.Debugf("Found branch config for branch %s with release type %s", currentBranch, releaseType) switch releaseType { case "rc", "beta", "alpha": - newVersion = incPrerelease(releaseType, newVersion) + newVersion = s.incPrerelease(releaseType, newVersion) case "release": if len(result["major"]) > 0 { newVersion = newVersion.IncMajor() @@ -102,121 +119,83 @@ func (s *SemanticRelease) GetNextVersion(repo string, force bool) (string, error } } - log.Infof("New version %s -> %s", lastVersion.String(), newVersion.String()) - err = saveToCache(util, lastVersion, &newVersion) - if err != nil { - return "", err + releaseVersion := shared.ReleaseVersion{ + Next: shared.ReleaseVersionEntry{ + Commit: hash, + Version: &newVersion, + }, + Last: shared.ReleaseVersionEntry{ + Commit: lastVersionHash, + Version: lastVersion, + }, + Branch: currentBranch, } - return newVersion.String(), err + + log.Infof("New version %s -> %s", lastVersion.String(), newVersion.String()) + err = s.saveToCache(releaseVersion) + if err != nil { + return nil, err + } + return &releaseVersion, err } //SetVersion for git repository -func (s *SemanticRelease) SetVersion(version string, repo string) error { - - util, err := gitutil.New(repo) - if err != nil { - return err - } +func (s *SemanticRelease) SetVersion(version string) error { newVersion, err := semver.NewVersion(version) if err != nil { return err } - lastVersion, _, err := util.GetLastVersion() + lastVersion, lastVersionHash, err := s.gitutil.GetLastVersion() + if err != nil { + return err + } + if lastVersion == nil { + lastVersion, _ = semver.NewVersion("1.0.0") + } + + hash, err := s.gitutil.GetHash() 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() + currentBranch, err := s.gitutil.GetBranch() if err != nil { return err } - branch, err := util.GetBranch() - if err != nil { - return err - } - - newVersionContent := cache.VersionFileContent{ - Commit: hash, - NextVersion: nextVersion.String(), - Branch: branch, - } - - if lastVersion != nil { - newVersionContent.Version = lastVersion.String() - } - - log.Debugf("Save %s with hash %s to cache", nextVersion.String(), hash) - 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 + return s.saveToCache(shared.ReleaseVersion{ + Next: shared.ReleaseVersionEntry{ + Commit: hash, + Version: newVersion, + }, + Last: shared.ReleaseVersionEntry{ + Commit: lastVersionHash, + Version: lastVersion, + }, + Branch: currentBranch, + }) } // GetChangelog from last version till now -func (s *SemanticRelease) GetChangelog(repo string) (string, error) { - nextVersion, err := s.GetNextVersion(repo, false) +func (s *SemanticRelease) GetChangelog(releaseVersion *shared.ReleaseVersion) (*shared.GeneratedChangelog, error) { + commits, err := s.gitutil.GetCommits(releaseVersion.Last.Commit) if err != nil { - log.Debugf("Could not get next version") - return "", err + return nil, err } - util, err := gitutil.New(repo) - if err != nil { - return "", err - } - - _, lastVersionHash, err := util.GetLastVersion() - if err != nil { - return "", err - } - - commits, err := util.GetCommits(lastVersionHash) - if err != nil { - return "", err - } + result := s.analyzer.Analyze(commits) log.Debugf("Found %d commits till last release", len(commits)) - a, err := analyzer.New(s.config.CommitFormat, s.config.Changelog) - if err != nil { - return "", err - } - result := a.Analyze(commits) - - c := changelog.New(s.config, a.GetRules()) - _, content, err := c.GenerateChanglog(nextVersion, s.config.GetRepositoryURL()+"/commit/{{hash}}", result) - if err != nil { - return "", err - } - return content, nil + c := changelog.New(s.config, s.analyzer.GetRules()) + return c.GenerateChanglog(shared.ChangelogTemplateConfig{ + Version: releaseVersion.Next.Version.String(), + Hash: releaseVersion.Last.Commit, + CommitURL: s.releaser.GetCommitURL(), + CompareURL: s.releaser.GetCompareURL(releaseVersion.Last.Version.String(), releaseVersion.Next.Version.String()), + }, result) } @@ -226,38 +205,37 @@ func (s *SemanticRelease) WriteChangeLog(changelogContent, file string) error { } // Release pusblish release to provider -func (s *SemanticRelease) Release(repo string) error { - util, err := gitutil.New(repo) - if err != nil { - return err - } - currentBranch, err := util.GetBranch() +func (s *SemanticRelease) Release(force bool) error { + currentBranch, err := s.gitutil.GetBranch() if _, ok := s.config.Branch[currentBranch]; !ok { log.Debugf("Will not perform a new release. Current %s branch is not configured in release config", currentBranch) return nil } - nextVersion, err := s.GetNextVersion(repo, false) + releaseVersion, err := s.GetNextVersion(force) if err != nil { log.Debugf("Could not get next version") return err } - changelog, err := s.GetChangelog(repo) + generatedChanglog, err := s.GetChangelog(releaseVersion) if err != nil { log.Debugf("Could not get changelog") return err } - releaseTitle := fmt.Sprintf("%s v%s", s.config.ReleaseTitle, nextVersion) - releaser, err := releaser.New(s.config).GetReleaser() if err != nil { return err } - if err = releaser.CreateRelease(nextVersion, releaseTitle, changelog, "master"); err != nil { + err = releaser.ValidateConfig() + if err != nil { + return err + } + + if err = releaser.CreateRelease(releaseVersion, generatedChanglog); err != nil { return err } From efcea0fafd4188887a401f419bdc8c677e9ce187 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Sat, 15 Jun 2019 23:16:30 +0200 Subject: [PATCH 31/77] style(*): fix lint issues --- .golangci.yml | 2 +- .travis.yml | 2 +- internal/analyzer/analyzer.go | 2 +- internal/analyzer/angular.go | 2 +- internal/cache/cache.go | 4 ++-- internal/releaser/github/github.go | 28 ++++++++++++------------- internal/releaser/releaser.go | 27 ++++++++++++------------ pkg/semanticrelease/semantic-release.go | 3 +++ 8 files changed, 36 insertions(+), 34 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 0e24022..51f24bf 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -5,7 +5,7 @@ linters-settings: golint: min-confidence: 0 issues: - exclude-use-default: false + exclude-use-default: true linters: enable: - golint \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index d078e60..9e5af48 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ dist: xenial language: go go: - 1.12.x - +gobuild_args: -x -ldflags cache: directories: - $HOME/.cache/go-build diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go index 60e7e56..7f1f21f 100644 --- a/internal/analyzer/analyzer.go +++ b/internal/analyzer/analyzer.go @@ -50,7 +50,7 @@ func New(format string, config config.ChangelogConfig) (*Analyzer, error) { log.Debugf("Commit format set to angular") analyzer.analyzeCommit = newAngular() default: - return nil, fmt.Errorf("Invalid commit format: %s", format) + return nil, fmt.Errorf("invalid commit format: %s", format) } return analyzer, nil diff --git a/internal/analyzer/angular.go b/internal/analyzer/angular.go index d05cff5..e36499a 100644 --- a/internal/analyzer/angular.go +++ b/internal/analyzer/angular.go @@ -107,6 +107,6 @@ func (a *angular) analyze(commit gitutil.Commit, rule Rule) (AnalyzedCommit, boo } } log.Tracef("%s does not match %s, skip", commit.Message, rule.Tag) - return analyzed, false, fmt.Errorf("Not found") + return analyzed, false, fmt.Errorf("not found") } diff --git a/internal/cache/cache.go b/internal/cache/cache.go index cb03426..7bc027d 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -8,14 +8,14 @@ import ( "gopkg.in/yaml.v2" ) -// VersionFileContent struct +// ReleaseVersion struct type ReleaseVersion struct { Last ReleaseVersionEntry `yaml:"last"` Next ReleaseVersionEntry `yaml:"next"` Branch string `yaml:"branch"` } -//VersionFileEntry struct +//ReleaseVersionEntry struct type ReleaseVersionEntry struct { Commit string `yaml:"commit"` Version string `yaml:"version"` diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index f9b9484..66a7043 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -17,8 +17,8 @@ import ( // GITHUB identifer for github interface const GITHUB = "github" -// GitHubReleaser type struct -type GitHubReleaser struct { +// Client type struct +type Client struct { config *config.GitHubProvider client *github.Client context context.Context @@ -28,7 +28,7 @@ type GitHubReleaser struct { } // New initialize a new GitHubRelease -func New(c *config.GitHubProvider) (*GitHubReleaser, error) { +func New(c *config.GitHubProvider) (*Client, error) { ctx := context.Background() httpClient := util.CreateBearerHTTPClient(ctx, c.AccessToken) @@ -41,7 +41,7 @@ func New(c *config.GitHubProvider) (*GitHubReleaser, error) { client, err = github.NewEnterpriseClient(c.CustomURL, c.CustomURL+"/api/v3/", httpClient) baseURL = c.CustomURL } - return &GitHubReleaser{ + return &Client{ config: c, client: client, context: ctx, @@ -50,30 +50,30 @@ func New(c *config.GitHubProvider) (*GitHubReleaser, error) { } //GetCommitURL for github -func (g GitHubReleaser) GetCommitURL() string { +func (g Client) GetCommitURL() string { return fmt.Sprintf("%s/%s/%s/commit/{{hash}}", g.baseURL, g.config.User, g.config.Repo) } //GetCompareURL for github -func (g GitHubReleaser) GetCompareURL(oldVersion, newVersion string) string { +func (g Client) GetCompareURL(oldVersion, newVersion string) string { return fmt.Sprintf("%s/%s/%s/compare/%s...%s", g.baseURL, g.config.User, g.config.Repo, oldVersion, newVersion) } //ValidateConfig for github -func (g GitHubReleaser) ValidateConfig() error { +func (g Client) ValidateConfig() error { if g.config.Repo == "" { - return fmt.Errorf("Github Repro is not set") + return fmt.Errorf("github Repro is not set") } if g.config.User == "" { - return fmt.Errorf("Github User is not set") + return fmt.Errorf("github User is not set") } envName := fmt.Sprintf("%s_ACCESS_TOKEN", strings.ToUpper(GITHUB)) token, isSet := os.LookupEnv(envName) if !isSet { - return fmt.Errorf("Can not find environment variable %s", envName) + return fmt.Errorf("can not find environment variable %s", envName) } g.token = token return nil @@ -81,7 +81,7 @@ func (g GitHubReleaser) ValidateConfig() error { } // CreateRelease creates release on remote -func (g GitHubReleaser) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error { +func (g Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error { tag := releaseVersion.Next.Version.String() prerelease := releaseVersion.Next.Version.Prerelease() != "" @@ -95,11 +95,11 @@ func (g GitHubReleaser) CreateRelease(releaseVersion *shared.ReleaseVersion, gen }) if err != nil { - return fmt.Errorf("Could not create release: %v", err) + return fmt.Errorf("could not create release: %v", err) } if resp.StatusCode >= http.StatusBadRequest { - return fmt.Errorf("Could not create release: response statuscode: %s", resp.Status) + return fmt.Errorf("could not create release: response statuscode: %s", resp.Status) } g.release = release @@ -108,7 +108,7 @@ func (g GitHubReleaser) CreateRelease(releaseVersion *shared.ReleaseVersion, gen } // UploadAssets uploads specified assets -func (g GitHubReleaser) UploadAssets(assets []config.Asset) error { +func (g Client) UploadAssets(assets []config.Asset) error { for _, asset := range assets { file, err := os.Open(asset.Name) if err != nil { diff --git a/internal/releaser/releaser.go b/internal/releaser/releaser.go index 6970fe2..e57c461 100644 --- a/internal/releaser/releaser.go +++ b/internal/releaser/releaser.go @@ -2,7 +2,6 @@ package releaser import ( "fmt" - "os" "github.com/Nightapes/go-semantic-release/internal/releaser/github" "github.com/Nightapes/go-semantic-release/internal/shared" @@ -37,22 +36,22 @@ func (r *Releasers) GetReleaser() (Releaser, error) { case github.GITHUB: return github.New(&r.config.GitHubProvider) } - return nil, fmt.Errorf("Could not initialize a releaser from this type: %s", r.config.Release) + return nil, fmt.Errorf("could not initialize a releaser from this type: %s", r.config.Release) } -func checkIfAssetsExists(assets []config.Asset) error { - var missingAssets []string - for _, asset := range assets { +// func checkIfAssetsExists(assets []config.Asset) error { +// var missingAssets []string +// for _, asset := range assets { - if _, err := os.Stat(asset.Name); err != nil { - missingAssets = append(missingAssets, asset.Name) - } - } +// if _, err := os.Stat(asset.Name); err != nil { +// missingAssets = append(missingAssets, asset.Name) +// } +// } - if len(missingAssets) != 0 { - return fmt.Errorf("Could not find specified Asset: %+v ", assets) - } +// if len(missingAssets) != 0 { +// return fmt.Errorf("could not find specified Asset: %+v ", assets) +// } - return nil +// return nil -} +// } diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index 61fca64..52c6f25 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -207,6 +207,9 @@ func (s *SemanticRelease) WriteChangeLog(changelogContent, file string) error { // Release pusblish release to provider func (s *SemanticRelease) Release(force bool) error { currentBranch, err := s.gitutil.GetBranch() + if err != nil { + return err + } if _, ok := s.config.Branch[currentBranch]; !ok { log.Debugf("Will not perform a new release. Current %s branch is not configured in release config", currentBranch) From 4326fd031370bb161b13eb6df031e858a7707575 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Sat, 15 Jun 2019 23:20:45 +0200 Subject: [PATCH 32/77] build(travis): change go import path --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9e5af48..8de50b9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ dist: xenial language: go go: - 1.12.x -gobuild_args: -x -ldflags +go_import_path: github.com/nightapes/go-semantic-release cache: directories: - $HOME/.cache/go-build From c578dc4cef8bb7a4293142cc315a9059c7a13842 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Sat, 15 Jun 2019 23:29:38 +0200 Subject: [PATCH 33/77] refactor(*): add missing files --- .gitignore | 1 + cmd/go-semantic-release/commands/changelog.go | 59 +++++++++++++++++++ cmd/go-semantic-release/commands/next.go | 45 ++++++++++++++ cmd/go-semantic-release/commands/release.go | 37 ++++++++++++ cmd/go-semantic-release/commands/root.go | 56 ++++++++++++++++++ cmd/go-semantic-release/commands/set.go | 36 +++++++++++ 6 files changed, 234 insertions(+) create mode 100644 cmd/go-semantic-release/commands/changelog.go create mode 100644 cmd/go-semantic-release/commands/next.go create mode 100644 cmd/go-semantic-release/commands/release.go create mode 100644 cmd/go-semantic-release/commands/root.go create mode 100644 cmd/go-semantic-release/commands/set.go diff --git a/.gitignore b/.gitignore index 7c8f013..068d872 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ *.dylib go-semantic-release +!cmd/go-semantic-release # Test binary, build with `go test -c` *.test diff --git a/cmd/go-semantic-release/commands/changelog.go b/cmd/go-semantic-release/commands/changelog.go new file mode 100644 index 0000000..98968f1 --- /dev/null +++ b/cmd/go-semantic-release/commands/changelog.go @@ -0,0 +1,59 @@ +package commands + +import ( + "github.com/Nightapes/go-semantic-release/pkg/semanticrelease" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +func init() { + changelogCmd.Flags().StringP("out", "o", "CHANGELOG.md", "Name of the file") + rootCmd.AddCommand(changelogCmd) +} + +var changelogCmd = &cobra.Command{ + Use: "changelog", + Short: "Generate changelog and save to file", + RunE: func(cmd *cobra.Command, args []string) error { + config, err := cmd.Flags().GetString("config") + if err != nil { + return err + } + + repository, err := cmd.Flags().GetString("repository") + if err != nil { + return err + } + + force, err := cmd.Flags().GetBool("no-cache") + if err != nil { + return err + } + + file, err := cmd.Flags().GetString("out") + if err != nil { + return err + } + + s, err := semanticrelease.New(readConfig(config), repository) + if err != nil { + return err + } + + releaseVersion, err := s.GetNextVersion(force) + if err != nil { + return err + } + + generatedChangelog, err := s.GetChangelog(releaseVersion) + if err != nil { + return err + } + + if err = s.WriteChangeLog(generatedChangelog.Content, file); err != nil { + log.Fatal(err) + } + + return nil + }, +} diff --git a/cmd/go-semantic-release/commands/next.go b/cmd/go-semantic-release/commands/next.go new file mode 100644 index 0000000..0f64259 --- /dev/null +++ b/cmd/go-semantic-release/commands/next.go @@ -0,0 +1,45 @@ +package commands + +import ( + "fmt" + + "github.com/Nightapes/go-semantic-release/pkg/semanticrelease" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(nextCmd) +} + +var nextCmd = &cobra.Command{ + Use: "next", + Short: "Get next release version", + RunE: func(cmd *cobra.Command, args []string) error { + config, err := cmd.Flags().GetString("config") + if err != nil { + return err + } + + repository, err := cmd.Flags().GetString("repository") + if err != nil { + return err + } + + force, err := cmd.Flags().GetBool("no-cache") + if err != nil { + return err + } + + s, err := semanticrelease.New(readConfig(config), repository) + if err != nil { + return err + } + + releaseVersion, err := s.GetNextVersion(force) + if err != nil { + return err + } + fmt.Println(releaseVersion.Next.Version.String()) + return nil + }, +} diff --git a/cmd/go-semantic-release/commands/release.go b/cmd/go-semantic-release/commands/release.go new file mode 100644 index 0000000..5b9d8be --- /dev/null +++ b/cmd/go-semantic-release/commands/release.go @@ -0,0 +1,37 @@ +package commands + +import ( + "github.com/Nightapes/go-semantic-release/pkg/semanticrelease" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(releaseCmd) +} + +var releaseCmd = &cobra.Command{ + Use: "release", + Short: "Make a release", + RunE: func(cmd *cobra.Command, args []string) error { + config, err := cmd.Flags().GetString("config") + if err != nil { + return err + } + + repository, err := cmd.Flags().GetString("repository") + if err != nil { + return err + } + + force, err := cmd.Flags().GetBool("force") + if err != nil { + return err + } + + s, err := semanticrelease.New(readConfig(config), repository) + if err != nil { + return err + } + return s.Release(force) + }, +} diff --git a/cmd/go-semantic-release/commands/root.go b/cmd/go-semantic-release/commands/root.go new file mode 100644 index 0000000..5c4ccd0 --- /dev/null +++ b/cmd/go-semantic-release/commands/root.go @@ -0,0 +1,56 @@ +package commands + +import ( + "fmt" + "os" + + "github.com/Nightapes/go-semantic-release/pkg/config" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +var rootCmd = &cobra.Command{ + Use: "go-semantic-release", + Short: "Make simple releases", + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + level, err := cmd.Flags().GetString("loglevel") + if err != nil { + return err + } + setLoglevel(level) + return nil + }, +} + +//Execute rootCmd +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func init() { + rootCmd.PersistentFlags().StringP("repository", "r", "", "Path to repository") + rootCmd.PersistentFlags().StringP("loglevel", "l", "error", "Set loglevel") + rootCmd.PersistentFlags().StringP("config", "c", ".release.yml", "Path to config file") + rootCmd.PersistentFlags().Bool("no-cache", false, "Ignore cache, don't use in ci build") +} + +func readConfig(file string) *config.ReleaseConfig { + releaseConfig, err := config.Read(file) + if err != nil { + log.Fatal(err) + } + return releaseConfig +} + +func setLoglevel(level string) { + parsed, err := log.ParseLevel(level) + if err != nil { + log.Errorf("Invalid loglevel %s", level) + } else { + log.SetLevel(parsed) + } + +} diff --git a/cmd/go-semantic-release/commands/set.go b/cmd/go-semantic-release/commands/set.go new file mode 100644 index 0000000..2f580fe --- /dev/null +++ b/cmd/go-semantic-release/commands/set.go @@ -0,0 +1,36 @@ +package commands + +import ( + "github.com/Nightapes/go-semantic-release/pkg/semanticrelease" + + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(setCmd) +} + +var setCmd = &cobra.Command{ + Use: "set [version]", + Args: cobra.ExactArgs(1), + Short: "Set next release version", + RunE: func(cmd *cobra.Command, args []string) error { + + config, err := cmd.Flags().GetString("config") + if err != nil { + return err + } + + repository, err := cmd.Flags().GetString("repository") + if err != nil { + return err + } + + s, err := semanticrelease.New(readConfig(config), repository) + if err != nil { + return err + } + + return s.SetVersion(args[0]) + }, +} From 065070657cfdc160f5d257f287e536e748e7fbf1 Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Mon, 17 Jun 2019 22:26:32 +0200 Subject: [PATCH 34/77] fix(cmd/commands/next): initialize force flag with default bool 'false' --- cmd/go-semantic-release/commands/release.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/go-semantic-release/commands/release.go b/cmd/go-semantic-release/commands/release.go index 5b9d8be..6126c0e 100644 --- a/cmd/go-semantic-release/commands/release.go +++ b/cmd/go-semantic-release/commands/release.go @@ -7,6 +7,8 @@ import ( func init() { rootCmd.AddCommand(releaseCmd) + releaseCmd.Flags().BoolP("force", "f", false, "") + } var releaseCmd = &cobra.Command{ From 8efde6386516ff3370558100ccc31995011432b7 Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Mon, 17 Jun 2019 22:30:17 +0200 Subject: [PATCH 35/77] fix(internal/releaser): add helper method to lookup for provider accesToken in environment variabels --- internal/releaser/github/github.go | 10 ++++++++-- internal/releaser/util/util.go | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index 66a7043..a8de1b6 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -29,16 +29,22 @@ type Client struct { // New initialize a new GitHubRelease func New(c *config.GitHubProvider) (*Client, error) { + var err error + + if c.AccessToken, err = util.GetAccessToken(GITHUB); err != nil { + return &Client{}, err + } ctx := context.Background() httpClient := util.CreateBearerHTTPClient(ctx, c.AccessToken) var client *github.Client - var err error baseURL := "https://github.com" if c.CustomURL == "" { client = github.NewClient(httpClient) } else { - client, err = github.NewEnterpriseClient(c.CustomURL, c.CustomURL+"/api/v3/", httpClient) + if client, err = github.NewEnterpriseClient(c.CustomURL, c.CustomURL+"/api/v3/", httpClient); err != nil { + return &Client{}, err + } baseURL = c.CustomURL } return &Client{ diff --git a/internal/releaser/util/util.go b/internal/releaser/util/util.go index 6479ace..50d42fb 100644 --- a/internal/releaser/util/util.go +++ b/internal/releaser/util/util.go @@ -2,7 +2,10 @@ package util import ( "context" + "fmt" "net/http" + "os" + "strings" "golang.org/x/oauth2" ) @@ -17,3 +20,15 @@ func CreateBearerHTTPClient(ctx context.Context, token string) *http.Client { return client } + +// GetAccessToken lookup for the providers accesstoken +func GetAccessToken(providerName string) (string, error) { + var token string + var exists bool + envName := fmt.Sprintf("%s_ACCESS_TOKEN", strings.ToUpper(providerName)) + + if token, exists = os.LookupEnv(envName); !exists { + return "", fmt.Errorf("Could not find %s in the enviroment variables. Please check if it is set", envName) + } + return token, nil +} From f65b90975f2cab24818d7baf99493fbe931a113d Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Mon, 17 Jun 2019 22:45:49 +0200 Subject: [PATCH 36/77] chore(internal/releaser): add further log messages --- internal/releaser/github/github.go | 8 +++++++- internal/releaser/releaser.go | 2 ++ internal/releaser/util/util.go | 3 +++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index a8de1b6..23e1dce 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -12,6 +12,7 @@ import ( "github.com/Nightapes/go-semantic-release/pkg/config" "github.com/google/go-github/v25/github" + log "github.com/sirupsen/logrus" ) // GITHUB identifer for github interface @@ -67,6 +68,7 @@ func (g Client) GetCompareURL(oldVersion, newVersion string) string { //ValidateConfig for github func (g Client) ValidateConfig() error { + log.Debugf("validate GitHub provider config") if g.config.Repo == "" { return fmt.Errorf("github Repro is not set") @@ -90,6 +92,7 @@ func (g Client) ValidateConfig() error { func (g Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error { tag := releaseVersion.Next.Version.String() + log.Debugf("create relase with for version %s", tag) prerelease := releaseVersion.Next.Version.Prerelease() != "" release, resp, err := g.client.Repositories.CreateRelease(g.context, g.config.User, g.config.Repo, &github.RepositoryRelease{ TagName: &tag, @@ -105,10 +108,13 @@ func (g Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedCh } if resp.StatusCode >= http.StatusBadRequest { - return fmt.Errorf("could not create release: response statuscode: %s", resp.Status) + return fmt.Errorf("ould not create release: response statuscode: %s", resp.Status) } + log.Infof("Crated release") g.release = release + log.Debugf("Release repsone: %+v", *release) + return nil } diff --git a/internal/releaser/releaser.go b/internal/releaser/releaser.go index e57c461..f5ace38 100644 --- a/internal/releaser/releaser.go +++ b/internal/releaser/releaser.go @@ -7,6 +7,7 @@ import ( "github.com/Nightapes/go-semantic-release/internal/shared" "github.com/Nightapes/go-semantic-release/pkg/config" + log "github.com/sirupsen/logrus" ) // Releasers struct type @@ -34,6 +35,7 @@ func New(c *config.ReleaseConfig) *Releasers { func (r *Releasers) GetReleaser() (Releaser, error) { switch r.config.Release { case github.GITHUB: + log.Debugf("initialize new %s-provider", github.GITHUB) return github.New(&r.config.GitHubProvider) } return nil, fmt.Errorf("could not initialize a releaser from this type: %s", r.config.Release) diff --git a/internal/releaser/util/util.go b/internal/releaser/util/util.go index 50d42fb..e0700ad 100644 --- a/internal/releaser/util/util.go +++ b/internal/releaser/util/util.go @@ -7,6 +7,7 @@ import ( "os" "strings" + log "github.com/sirupsen/logrus" "golang.org/x/oauth2" ) @@ -27,6 +28,8 @@ func GetAccessToken(providerName string) (string, error) { var exists bool envName := fmt.Sprintf("%s_ACCESS_TOKEN", strings.ToUpper(providerName)) + log.Debugf("check if %s environment variable is set", envName) + if token, exists = os.LookupEnv(envName); !exists { return "", fmt.Errorf("Could not find %s in the enviroment variables. Please check if it is set", envName) } From b0d28b1ce79a246094e9912e7f9aad8eaa0a2ef1 Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Tue, 18 Jun 2019 21:20:30 +0200 Subject: [PATCH 37/77] chore(internal/releaser/github): remove unused token initialization in ValidateConfig() because token gets initialiazed in New() --- internal/releaser/github/github.go | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index 23e1dce..a47d3fa 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -5,7 +5,6 @@ import ( "fmt" "net/http" "os" - "strings" "github.com/Nightapes/go-semantic-release/internal/releaser/util" "github.com/Nightapes/go-semantic-release/internal/shared" @@ -78,12 +77,6 @@ func (g Client) ValidateConfig() error { return fmt.Errorf("github User is not set") } - envName := fmt.Sprintf("%s_ACCESS_TOKEN", strings.ToUpper(GITHUB)) - token, isSet := os.LookupEnv(envName) - if !isSet { - return fmt.Errorf("can not find environment variable %s", envName) - } - g.token = token return nil } @@ -104,11 +97,11 @@ func (g Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedCh }) if err != nil { - return fmt.Errorf("could not create release: %v", err) + return fmt.Errorf("Could not create release: %v", err) } if resp.StatusCode >= http.StatusBadRequest { - return fmt.Errorf("ould not create release: response statuscode: %s", resp.Status) + return fmt.Errorf("Could not create release: response statuscode: %s", resp.Status) } log.Infof("Crated release") From 7de6f249fe2091d38727b71062ce30baa94d9fe6 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 18 Jun 2019 21:35:51 +0200 Subject: [PATCH 38/77] build(travis): add release config --- .release.yml | 6 ++++-- .travis.yml | 8 +++++--- cmd/go-semantic-release/commands/release.go | 4 +--- cmd/go-semantic-release/commands/root.go | 3 ++- cmd/go-semantic-release/main.go | 4 +++- internal/releaser/github/github.go | 2 +- internal/releaser/util/util.go | 2 +- 7 files changed, 17 insertions(+), 12 deletions(-) diff --git a/.release.yml b/.release.yml index c26bd48..27603d4 100644 --- a/.release.yml +++ b/.release.yml @@ -12,8 +12,10 @@ changelog: templatePath: '' release: 'github' assets: - - name: - compress: + - name: ./build/go-semantic-release + compress: false + - name: ./build/go-semantic-release.exe + compress: false github: repo: "go-semantic-release" user: "nightapes" diff --git a/.travis.yml b/.travis.yml index 8de50b9..d43de70 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,9 +27,11 @@ before_script: script: - golangci-lint run ./... - go test -v ./... - - go build -o build/go-semantic-release ./cmd/go-semantic-release/ - - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe ./cmd/go-semantic-release/ - + - echo "Building version `./go-semantic-release next`" + - go build -o build/go-semantic-release-temp ./cmd/go-semantic-release/ + - go build -o build/go-semantic-release ./cmd/go-semantic-release/ -ldflags "-X main.minversion `./go-semantic-release next`" + - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe -ldflags "-X main.minversion `./go-semantic-release next`" ./cmd/go-semantic-release/ + branches: except: - /^v\d+\.\d+\.\d+$/ \ No newline at end of file diff --git a/cmd/go-semantic-release/commands/release.go b/cmd/go-semantic-release/commands/release.go index 6126c0e..7d981ca 100644 --- a/cmd/go-semantic-release/commands/release.go +++ b/cmd/go-semantic-release/commands/release.go @@ -7,8 +7,6 @@ import ( func init() { rootCmd.AddCommand(releaseCmd) - releaseCmd.Flags().BoolP("force", "f", false, "") - } var releaseCmd = &cobra.Command{ @@ -25,7 +23,7 @@ var releaseCmd = &cobra.Command{ return err } - force, err := cmd.Flags().GetBool("force") + force, err := cmd.Flags().GetBool("no-cache") if err != nil { return err } diff --git a/cmd/go-semantic-release/commands/root.go b/cmd/go-semantic-release/commands/root.go index 5c4ccd0..c193476 100644 --- a/cmd/go-semantic-release/commands/root.go +++ b/cmd/go-semantic-release/commands/root.go @@ -23,7 +23,8 @@ var rootCmd = &cobra.Command{ } //Execute rootCmd -func Execute() { +func Execute(version string) { + rootCmd.Version = version if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) diff --git a/cmd/go-semantic-release/main.go b/cmd/go-semantic-release/main.go index a31920a..24dbfef 100644 --- a/cmd/go-semantic-release/main.go +++ b/cmd/go-semantic-release/main.go @@ -4,6 +4,8 @@ import ( "github.com/Nightapes/go-semantic-release/cmd/go-semantic-release/commands" ) +var version string + func main() { - commands.Execute() + commands.Execute(version) } diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index 23e1dce..ecc5400 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -127,7 +127,7 @@ func (g Client) UploadAssets(assets []config.Asset) error { return err } - _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.User, g.config.Repo, *g.release.ID, &github.UploadOptions{Name: asset.Name}, file) + _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.User, g.config.Repo, *g.release.ID, &github.UploadOptions{Name: file.Name()}, file) if err != nil { return err } diff --git a/internal/releaser/util/util.go b/internal/releaser/util/util.go index e0700ad..cfbf40b 100644 --- a/internal/releaser/util/util.go +++ b/internal/releaser/util/util.go @@ -31,7 +31,7 @@ func GetAccessToken(providerName string) (string, error) { log.Debugf("check if %s environment variable is set", envName) if token, exists = os.LookupEnv(envName); !exists { - return "", fmt.Errorf("Could not find %s in the enviroment variables. Please check if it is set", envName) + return "", fmt.Errorf("could not find %s in the enviroment variables. Please check if it is set", envName) } return token, nil } From e2eee63ac5aaab79aba726e84971e4972e5f4ced Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 18 Jun 2019 21:36:56 +0200 Subject: [PATCH 39/77] style(lint): fix lint issues --- internal/releaser/github/github.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index f96f3bd..98857ae 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -24,7 +24,6 @@ type Client struct { context context.Context release *github.RepositoryRelease baseURL string - token string } // New initialize a new GitHubRelease @@ -97,11 +96,11 @@ func (g Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedCh }) if err != nil { - return fmt.Errorf("Could not create release: %v", err) + return fmt.Errorf("could not create release: %v", err) } if resp.StatusCode >= http.StatusBadRequest { - return fmt.Errorf("Could not create release: response statuscode: %s", resp.Status) + return fmt.Errorf("could not create release: response statuscode: %s", resp.Status) } log.Infof("Crated release") From 06997c1bfd2e63b35bf4599a87b0599006265426 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 18 Jun 2019 21:40:58 +0200 Subject: [PATCH 40/77] build(travis): fix go build flags --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d43de70..c179963 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,8 +29,8 @@ script: - go test -v ./... - echo "Building version `./go-semantic-release next`" - go build -o build/go-semantic-release-temp ./cmd/go-semantic-release/ - - go build -o build/go-semantic-release ./cmd/go-semantic-release/ -ldflags "-X main.minversion `./go-semantic-release next`" - - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe -ldflags "-X main.minversion `./go-semantic-release next`" ./cmd/go-semantic-release/ + - go build -o build/go-semantic-release ./cmd/go-semantic-release/ -ldflags "-X main.version `./go-semantic-release next`" + - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe -ldflags "-X main.version `./go-semantic-release next`" ./cmd/go-semantic-release/ branches: except: From fff432d8a85011b5a1f2e684c85a7203dfadf8ee Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 18 Jun 2019 21:47:31 +0200 Subject: [PATCH 41/77] build(travis): fix go lang build --- .travis.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index c179963..556e8fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,11 +27,14 @@ before_script: script: - golangci-lint run ./... - go test -v ./... - - echo "Building version `./go-semantic-release next`" - go build -o build/go-semantic-release-temp ./cmd/go-semantic-release/ - - go build -o build/go-semantic-release ./cmd/go-semantic-release/ -ldflags "-X main.version `./go-semantic-release next`" - - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe -ldflags "-X main.version `./go-semantic-release next`" ./cmd/go-semantic-release/ - + - echo "Building version `./build/go-semantic-release-temp next`" + - go build -o build/go-semantic-release -ldflags "-X main.version=`./go-semantic-release next`" ./cmd/go-semantic-release/ + - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe -ldflags "-X main.version=`./go-semantic-release next`" ./cmd/go-semantic-release/ + +after_success + - ./build/go-semantic-release-temp release + branches: except: - /^v\d+\.\d+\.\d+$/ \ No newline at end of file From 443e2ba35c7dbfb30683e98efdf409018fbe2290 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 18 Jun 2019 21:48:26 +0200 Subject: [PATCH 42/77] buuild(travis): fix after_success --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 556e8fb..16d2b75 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ script: - go build -o build/go-semantic-release -ldflags "-X main.version=`./go-semantic-release next`" ./cmd/go-semantic-release/ - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe -ldflags "-X main.version=`./go-semantic-release next`" ./cmd/go-semantic-release/ -after_success +after_success: - ./build/go-semantic-release-temp release branches: From 0eafe84d68d6072d763f149aada1e934cf037a58 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 18 Jun 2019 22:03:36 +0200 Subject: [PATCH 43/77] build(travis): add checkout master --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 16d2b75..41e48b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,9 +15,6 @@ services: notifications: email: false -git: - depth: 1 - env: - GO111MODULE=on @@ -26,6 +23,7 @@ before_script: script: - golangci-lint run ./... + - git checkout master - go test -v ./... - go build -o build/go-semantic-release-temp ./cmd/go-semantic-release/ - echo "Building version `./build/go-semantic-release-temp next`" From e4ba4834ebb24973d3492f363be499f635361ce3 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 18 Jun 2019 22:59:07 +0200 Subject: [PATCH 44/77] fix(branch): get branch from detached HEAD --- .travis.yml | 4 +++- internal/gitutil/gitutil.go | 24 ++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 41e48b2..29643a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,8 @@ dist: xenial +git: + depth: false + language: go go: - 1.12.x @@ -23,7 +26,6 @@ before_script: script: - golangci-lint run ./... - - git checkout master - go test -v ./... - go build -o build/go-semantic-release-temp ./cmd/go-semantic-release/ - echo "Building version `./build/go-semantic-release-temp next`" diff --git a/internal/gitutil/gitutil.go b/internal/gitutil/gitutil.go index a721f4c..8e41517 100644 --- a/internal/gitutil/gitutil.go +++ b/internal/gitutil/gitutil.go @@ -54,9 +54,29 @@ func (g *GitUtil) GetBranch() (string, error) { } if !ref.Name().IsBranch() { - return "", fmt.Errorf("no branch found, found %s, please checkout a branch (git checkout )", ref.Name().String()) - } + branches, err := g.Repository.Branches() + if err != nil { + return "", err + } + var currentBranch string + found := branches.ForEach(func(p *plumbing.Reference) error { + + if p.Name().IsBranch() && p.Name().Short() != "origin" { + currentBranch = p.Name().Short() + return fmt.Errorf("break") + } + return nil + }) + + if found != nil { + log.Debugf("Found branch from HEAD %s", currentBranch) + return currentBranch, nil + } + + return "", fmt.Errorf("no branch found, found %s, please checkout a branch (git checkout -b )", ref.Name().String()) + } + log.Debugf("Found branch %s", ref.Name().Short()) return ref.Name().Short(), nil } From 849dc6c5b76736d8958412fd2b7e76a303102b3c Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 20 Jun 2019 00:46:59 +0200 Subject: [PATCH 45/77] feat(analyzer): add 'DRAFT' as messeage identifier --- internal/analyzer/analyzer.go | 8 ++++-- internal/analyzer/angular.go | 34 +++++++++++++++++-------- internal/shared/shared.go | 7 ++--- pkg/semanticrelease/semantic-release.go | 6 ++++- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go index 7f1f21f..a5b1def 100644 --- a/internal/analyzer/analyzer.go +++ b/internal/analyzer/analyzer.go @@ -24,7 +24,7 @@ type Rule struct { } type analyzeCommit interface { - analyze(commit gitutil.Commit, tag Rule) (AnalyzedCommit, bool, error) + analyze(commit gitutil.Commit, tag Rule) (AnalyzedCommit, bool, bool, error) getRules() []Rule } @@ -34,6 +34,7 @@ type AnalyzedCommit struct { ParsedMessage string Scope string ParsedBreakingChangeMessage string + ParsedDraftMessage string Tag string TagString string Print bool @@ -68,11 +69,12 @@ func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit analyzedCommits["major"] = make([]AnalyzedCommit, 0) analyzedCommits["minor"] = make([]AnalyzedCommit, 0) analyzedCommits["patch"] = make([]AnalyzedCommit, 0) + analyzedCommits["draft"] = make([]AnalyzedCommit, 0) analyzedCommits["none"] = make([]AnalyzedCommit, 0) for _, commit := range commits { for _, rule := range a.analyzeCommit.getRules() { - analyzedCommit, hasBreakingChange, err := a.analyzeCommit.analyze(commit, rule) + analyzedCommit, hasBreakingChange, isDraft, err := a.analyzeCommit.analyze(commit, rule) if err == nil { if a.Config.PrintAll { analyzedCommit.Print = true @@ -81,6 +83,8 @@ func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit } if hasBreakingChange { analyzedCommits["major"] = append(analyzedCommits["major"], analyzedCommit) + } else if isDraft { + analyzedCommits["draft"] = append(analyzedCommits["draft"], analyzedCommit) } else { analyzedCommits[rule.Release] = append(analyzedCommits[rule.Release], analyzedCommit) } diff --git a/internal/analyzer/angular.go b/internal/analyzer/angular.go index e36499a..8fdf7f5 100644 --- a/internal/analyzer/angular.go +++ b/internal/analyzer/angular.go @@ -76,7 +76,7 @@ func (a *angular) getRules() []Rule { return a.rules } -func (a *angular) analyze(commit gitutil.Commit, rule Rule) (AnalyzedCommit, bool, error) { +func (a *angular) analyze(commit gitutil.Commit, rule Rule) (AnalyzedCommit, bool, bool, error) { analyzed := AnalyzedCommit{ Commit: commit, @@ -92,21 +92,35 @@ func (a *angular) analyze(commit gitutil.Commit, rule Rule) (AnalyzedCommit, boo analyzed.Scope = matches[0][2] message := strings.Join(matches[0][3:], "") - splitted := strings.SplitN(message, "BREAKING CHANGE:", 1) + breakingChange := strings.SplitN(message, "BREAKING CHANGE:", 1) + draft := strings.SplitN(message, "DRAFT:", 1) - if len(splitted) == 1 { - analyzed.ParsedMessage = splitted[0] + if len(breakingChange) == 1 && len(draft) == 1 { + analyzed.ParsedMessage = breakingChange[0] log.Tracef("%s: found %s", commit.Message, rule.Tag) - return analyzed, false, nil + return analyzed, false, false, nil + + } + + if len(breakingChange) > 1 { + + analyzed.ParsedMessage = breakingChange[0] + analyzed.ParsedBreakingChangeMessage = breakingChange[1] + + log.Tracef(" %s, BREAKING CHANGE found", commit.Message) + + return analyzed, true, false, nil + + } else if len(draft) > 1 { + analyzed.ParsedMessage = draft[0] + analyzed.ParsedDraftMessage = draft[1] + log.Tracef(" %s, DRAFT found", commit.Message) + } - analyzed.ParsedMessage = splitted[0] - analyzed.ParsedBreakingChangeMessage = splitted[1] - log.Tracef(" %s, BREAKING CHANGE found", commit.Message) - return analyzed, true, nil } } log.Tracef("%s does not match %s, skip", commit.Message, rule.Tag) - return analyzed, false, fmt.Errorf("not found") + return analyzed, false, false, fmt.Errorf("not found") } diff --git a/internal/shared/shared.go b/internal/shared/shared.go index 3d0154a..b3579c7 100644 --- a/internal/shared/shared.go +++ b/internal/shared/shared.go @@ -13,8 +13,9 @@ type ReleaseVersion struct { //ReleaseVersionEntry struct type ReleaseVersionEntry struct { - Commit string - Version *semver.Version + Commit string + Draft bool + *semver.Version } //GeneratedChangelog struct @@ -23,7 +24,7 @@ type GeneratedChangelog struct { Content string } -//GenerateChangelogConfig struct +//ChangelogTemplateConfig struct type ChangelogTemplateConfig struct { CommitURL string CompareURL string diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index 52c6f25..63f2552 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -100,7 +100,7 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er return nil, err } result := a.Analyze(commits) - + var isDraft bool = false for branch, releaseType := range s.config.Branch { if currentBranch == branch || strings.HasPrefix(currentBranch, branch) { log.Debugf("Found branch config for branch %s with release type %s", currentBranch, releaseType) @@ -115,6 +115,9 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er } else if len(result["patch"]) > 0 { newVersion = newVersion.IncPatch() } + if len(result["draft"]) > 0 { + isDraft = true + } } } } @@ -123,6 +126,7 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er Next: shared.ReleaseVersionEntry{ Commit: hash, Version: &newVersion, + Draft: isDraft, }, Last: shared.ReleaseVersionEntry{ Commit: lastVersionHash, From 92d569c14cc938563030714c3a2958f197431922 Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 20 Jun 2019 00:48:07 +0200 Subject: [PATCH 46/77] feat(internal/releaser): add SetReleaseType Method to Releaser interface --- internal/releaser/github/github.go | 33 +++++++++++++++++-------- internal/releaser/releaser.go | 1 + pkg/semanticrelease/semantic-release.go | 2 ++ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index 98857ae..33e93a0 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -19,11 +19,12 @@ const GITHUB = "github" // Client type struct type Client struct { - config *config.GitHubProvider - client *github.Client - context context.Context - release *github.RepositoryRelease - baseURL string + config *config.GitHubProvider + client *github.Client + context context.Context + release *github.RepositoryRelease + draft, prerelease bool + baseURL string } // New initialize a new GitHubRelease @@ -64,6 +65,18 @@ func (g Client) GetCompareURL(oldVersion, newVersion string) string { return fmt.Sprintf("%s/%s/%s/compare/%s...%s", g.baseURL, g.config.User, g.config.Repo, oldVersion, newVersion) } +//SetReleaseType sets the provider release type +func (g Client) SetReleaseType(releaseVersion *shared.ReleaseVersion) { + if !releaseVersion.Next.Draft { + log.Debugf("Set release as draft") + g.draft = true + } + if releaseVersion.Next.Prerelease() != "" { + log.Debugf("Set release as prerelease") + g.prerelease = true + } +} + //ValidateConfig for github func (g Client) ValidateConfig() error { log.Debugf("validate GitHub provider config") @@ -83,16 +96,16 @@ func (g Client) ValidateConfig() error { // CreateRelease creates release on remote func (g Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error { - tag := releaseVersion.Next.Version.String() - log.Debugf("create relase with for version %s", tag) - prerelease := releaseVersion.Next.Version.Prerelease() != "" + tag := releaseVersion.Next.String() + log.Debugf("create release witth version %s", tag) + release, resp, err := g.client.Repositories.CreateRelease(g.context, g.config.User, g.config.Repo, &github.RepositoryRelease{ TagName: &tag, TargetCommitish: &releaseVersion.Branch, Name: &generatedChangelog.Title, Body: &generatedChangelog.Content, - Draft: &prerelease, - Prerelease: &prerelease, + Draft: &g.draft, + Prerelease: &g.prerelease, }) if err != nil { diff --git a/internal/releaser/releaser.go b/internal/releaser/releaser.go index f5ace38..63a897c 100644 --- a/internal/releaser/releaser.go +++ b/internal/releaser/releaser.go @@ -22,6 +22,7 @@ type Releaser interface { UploadAssets(assets []config.Asset) error GetCommitURL() string GetCompareURL(oldVersion, newVersion string) string + SetReleaseType(*shared.ReleaseVersion) } // New initialize a Relerser diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index 63f2552..ae2afac 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -242,6 +242,8 @@ func (s *SemanticRelease) Release(force bool) error { return err } + releaser.SetReleaseType(releaseVersion) + if err = releaser.CreateRelease(releaseVersion, generatedChanglog); err != nil { return err } From 88e49752cbc3b4d08984728e07c83260859b34f0 Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 20 Jun 2019 01:13:31 +0200 Subject: [PATCH 47/77] fix(internal/releaser/github): error handling for case if release already exists --- internal/releaser/github/github.go | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index 33e93a0..716f812 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" "os" + "strings" "github.com/Nightapes/go-semantic-release/internal/releaser/util" "github.com/Nightapes/go-semantic-release/internal/shared" @@ -109,19 +110,17 @@ func (g Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedCh }) if err != nil { - return fmt.Errorf("could not create release: %v", err) + if !strings.Contains(err.Error(), "already_exists") && resp.StatusCode >= http.StatusUnprocessableEntity { + return fmt.Errorf("could not create release: %v", err) + } + log.Infof("A release with tag %s already exits, will not perform a release or update", tag) + } else { + g.release = release + log.Debugf("Release repsone: %+v", *release) + log.Infof("Crated release") } - if resp.StatusCode >= http.StatusBadRequest { - return fmt.Errorf("could not create release: response statuscode: %s", resp.Status) - } - log.Infof("Crated release") - - g.release = release - log.Debugf("Release repsone: %+v", *release) - return nil - } // UploadAssets uploads specified assets From 62c6352aadc02a08bdbbb36cbf17a1c9f9894dcb Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 20 Jun 2019 02:00:39 +0200 Subject: [PATCH 48/77] chore(internal/releaser/github): fix setReleaseType --- internal/releaser/github/github.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index 716f812..0a05052 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -68,7 +68,7 @@ func (g Client) GetCompareURL(oldVersion, newVersion string) string { //SetReleaseType sets the provider release type func (g Client) SetReleaseType(releaseVersion *shared.ReleaseVersion) { - if !releaseVersion.Next.Draft { + if releaseVersion.Next.Draft { log.Debugf("Set release as draft") g.draft = true } From d36be78c9c5f9f3c3725c5f5f6a01b8a9a2f899e Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 20 Jun 2019 10:49:50 +0200 Subject: [PATCH 49/77] ref(releasetype/draft): infomation about if release is a draft will now be set in the sharedVersion --- internal/analyzer/analyzer.go | 8 ++---- internal/analyzer/angular.go | 33 ++++++++----------------- internal/cache/cache.go | 1 + internal/releaser/github/github.go | 31 ++++++++--------------- internal/releaser/releaser.go | 1 - internal/shared/shared.go | 6 ++--- pkg/semanticrelease/semantic-release.go | 10 +++----- 7 files changed, 29 insertions(+), 61 deletions(-) diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go index a5b1def..7f1f21f 100644 --- a/internal/analyzer/analyzer.go +++ b/internal/analyzer/analyzer.go @@ -24,7 +24,7 @@ type Rule struct { } type analyzeCommit interface { - analyze(commit gitutil.Commit, tag Rule) (AnalyzedCommit, bool, bool, error) + analyze(commit gitutil.Commit, tag Rule) (AnalyzedCommit, bool, error) getRules() []Rule } @@ -34,7 +34,6 @@ type AnalyzedCommit struct { ParsedMessage string Scope string ParsedBreakingChangeMessage string - ParsedDraftMessage string Tag string TagString string Print bool @@ -69,12 +68,11 @@ func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit analyzedCommits["major"] = make([]AnalyzedCommit, 0) analyzedCommits["minor"] = make([]AnalyzedCommit, 0) analyzedCommits["patch"] = make([]AnalyzedCommit, 0) - analyzedCommits["draft"] = make([]AnalyzedCommit, 0) analyzedCommits["none"] = make([]AnalyzedCommit, 0) for _, commit := range commits { for _, rule := range a.analyzeCommit.getRules() { - analyzedCommit, hasBreakingChange, isDraft, err := a.analyzeCommit.analyze(commit, rule) + analyzedCommit, hasBreakingChange, err := a.analyzeCommit.analyze(commit, rule) if err == nil { if a.Config.PrintAll { analyzedCommit.Print = true @@ -83,8 +81,6 @@ func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit } if hasBreakingChange { analyzedCommits["major"] = append(analyzedCommits["major"], analyzedCommit) - } else if isDraft { - analyzedCommits["draft"] = append(analyzedCommits["draft"], analyzedCommit) } else { analyzedCommits[rule.Release] = append(analyzedCommits[rule.Release], analyzedCommit) } diff --git a/internal/analyzer/angular.go b/internal/analyzer/angular.go index 8fdf7f5..391085c 100644 --- a/internal/analyzer/angular.go +++ b/internal/analyzer/angular.go @@ -76,7 +76,7 @@ func (a *angular) getRules() []Rule { return a.rules } -func (a *angular) analyze(commit gitutil.Commit, rule Rule) (AnalyzedCommit, bool, bool, error) { +func (a *angular) analyze(commit gitutil.Commit, rule Rule) (AnalyzedCommit, bool, error) { analyzed := AnalyzedCommit{ Commit: commit, @@ -92,35 +92,22 @@ func (a *angular) analyze(commit gitutil.Commit, rule Rule) (AnalyzedCommit, boo analyzed.Scope = matches[0][2] message := strings.Join(matches[0][3:], "") - breakingChange := strings.SplitN(message, "BREAKING CHANGE:", 1) - draft := strings.SplitN(message, "DRAFT:", 1) + if !strings.Contains(message, "BREAKING CHANGE:") { + analyzed.ParsedMessage = message - if len(breakingChange) == 1 && len(draft) == 1 { - analyzed.ParsedMessage = breakingChange[0] log.Tracef("%s: found %s", commit.Message, rule.Tag) - return analyzed, false, false, nil - + return analyzed, false, nil } + breakingChange := strings.SplitN(message, "BREAKING CHANGE:", 2) - if len(breakingChange) > 1 { - - analyzed.ParsedMessage = breakingChange[0] - analyzed.ParsedBreakingChangeMessage = breakingChange[1] - - log.Tracef(" %s, BREAKING CHANGE found", commit.Message) - - return analyzed, true, false, nil - - } else if len(draft) > 1 { - analyzed.ParsedMessage = draft[0] - analyzed.ParsedDraftMessage = draft[1] - log.Tracef(" %s, DRAFT found", commit.Message) - - } + analyzed.ParsedMessage = breakingChange[0] + analyzed.ParsedBreakingChangeMessage = breakingChange[1] + log.Tracef(" %s, BREAKING CHANGE found", commit.Message) + return analyzed, true, nil } } log.Tracef("%s does not match %s, skip", commit.Message, rule.Tag) - return analyzed, false, false, fmt.Errorf("not found") + return analyzed, false, fmt.Errorf("not found") } diff --git a/internal/cache/cache.go b/internal/cache/cache.go index 7bc027d..f3db59e 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -13,6 +13,7 @@ type ReleaseVersion struct { Last ReleaseVersionEntry `yaml:"last"` Next ReleaseVersionEntry `yaml:"next"` Branch string `yaml:"branch"` + Draft bool `yaml:"draft"` } //ReleaseVersionEntry struct diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index 0a05052..89e70ca 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -20,12 +20,11 @@ const GITHUB = "github" // Client type struct type Client struct { - config *config.GitHubProvider - client *github.Client - context context.Context - release *github.RepositoryRelease - draft, prerelease bool - baseURL string + config *config.GitHubProvider + client *github.Client + context context.Context + release *github.RepositoryRelease + baseURL string } // New initialize a new GitHubRelease @@ -66,18 +65,6 @@ func (g Client) GetCompareURL(oldVersion, newVersion string) string { return fmt.Sprintf("%s/%s/%s/compare/%s...%s", g.baseURL, g.config.User, g.config.Repo, oldVersion, newVersion) } -//SetReleaseType sets the provider release type -func (g Client) SetReleaseType(releaseVersion *shared.ReleaseVersion) { - if releaseVersion.Next.Draft { - log.Debugf("Set release as draft") - g.draft = true - } - if releaseVersion.Next.Prerelease() != "" { - log.Debugf("Set release as prerelease") - g.prerelease = true - } -} - //ValidateConfig for github func (g Client) ValidateConfig() error { log.Debugf("validate GitHub provider config") @@ -97,16 +84,18 @@ func (g Client) ValidateConfig() error { // CreateRelease creates release on remote func (g Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error { - tag := releaseVersion.Next.String() + tag := releaseVersion.Next.Version.String() log.Debugf("create release witth version %s", tag) + prerelease := releaseVersion.Next.Version.Prerelease() != "" + release, resp, err := g.client.Repositories.CreateRelease(g.context, g.config.User, g.config.Repo, &github.RepositoryRelease{ TagName: &tag, TargetCommitish: &releaseVersion.Branch, Name: &generatedChangelog.Title, Body: &generatedChangelog.Content, - Draft: &g.draft, - Prerelease: &g.prerelease, + Draft: &releaseVersion.Draft, + Prerelease: &prerelease, }) if err != nil { diff --git a/internal/releaser/releaser.go b/internal/releaser/releaser.go index 63a897c..f5ace38 100644 --- a/internal/releaser/releaser.go +++ b/internal/releaser/releaser.go @@ -22,7 +22,6 @@ type Releaser interface { UploadAssets(assets []config.Asset) error GetCommitURL() string GetCompareURL(oldVersion, newVersion string) string - SetReleaseType(*shared.ReleaseVersion) } // New initialize a Relerser diff --git a/internal/shared/shared.go b/internal/shared/shared.go index b3579c7..2630aab 100644 --- a/internal/shared/shared.go +++ b/internal/shared/shared.go @@ -9,13 +9,13 @@ type ReleaseVersion struct { Last ReleaseVersionEntry Next ReleaseVersionEntry Branch string + Draft bool } //ReleaseVersionEntry struct type ReleaseVersionEntry struct { - Commit string - Draft bool - *semver.Version + Commit string + Version *semver.Version } //GeneratedChangelog struct diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index ae2afac..2e655f0 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -100,13 +100,14 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er return nil, err } result := a.Analyze(commits) - var isDraft bool = false + isDraft := false for branch, releaseType := range s.config.Branch { if currentBranch == branch || strings.HasPrefix(currentBranch, branch) { log.Debugf("Found branch config for branch %s with release type %s", currentBranch, releaseType) switch releaseType { case "rc", "beta", "alpha": newVersion = s.incPrerelease(releaseType, newVersion) + isDraft = true case "release": if len(result["major"]) > 0 { newVersion = newVersion.IncMajor() @@ -115,9 +116,6 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er } else if len(result["patch"]) > 0 { newVersion = newVersion.IncPatch() } - if len(result["draft"]) > 0 { - isDraft = true - } } } } @@ -126,13 +124,13 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er Next: shared.ReleaseVersionEntry{ Commit: hash, Version: &newVersion, - Draft: isDraft, }, Last: shared.ReleaseVersionEntry{ Commit: lastVersionHash, Version: lastVersion, }, Branch: currentBranch, + Draft: isDraft, } log.Infof("New version %s -> %s", lastVersion.String(), newVersion.String()) @@ -242,8 +240,6 @@ func (s *SemanticRelease) Release(force bool) error { return err } - releaser.SetReleaseType(releaseVersion) - if err = releaser.CreateRelease(releaseVersion, generatedChanglog); err != nil { return err } From 49aaa93cac4d32cca9622cb78f2740d539aa909f Mon Sep 17 00:00:00 2001 From: Felix Wiedmann Date: Thu, 20 Jun 2019 11:39:37 +0200 Subject: [PATCH 50/77] feat(pkg/semanticrelease): rc is prerelease, beta & alpha are draft --- pkg/semanticrelease/semantic-release.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index 2e655f0..d9bc9dc 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -105,9 +105,10 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er if currentBranch == branch || strings.HasPrefix(currentBranch, branch) { log.Debugf("Found branch config for branch %s with release type %s", currentBranch, releaseType) switch releaseType { - case "rc", "beta", "alpha": - newVersion = s.incPrerelease(releaseType, newVersion) + case "beta", "alpha": isDraft = true + case "rc": + newVersion = s.incPrerelease(releaseType, newVersion) case "release": if len(result["major"]) > 0 { newVersion = newVersion.IncMajor() From 6e2fa0ddbf22b6dde8e88bdb96053b3a46c6807b Mon Sep 17 00:00:00 2001 From: fwiedmann Date: Sun, 7 Jul 2019 23:42:52 +0200 Subject: [PATCH 51/77] temp(pkg/releaser): add ZipFiles Method --- .release.yml | 2 +- go.mod | 45 ++++-- go.sum | 204 ++++++++++++++++++++++++ internal/releaser/github/github.go | 41 +++-- internal/releaser/releaser.go | 17 -- internal/releaser/util/util.go | 46 ++++++ pkg/semanticrelease/semantic-release.go | 4 + 7 files changed, 322 insertions(+), 37 deletions(-) diff --git a/.release.yml b/.release.yml index 27603d4..4c380f9 100644 --- a/.release.yml +++ b/.release.yml @@ -1,5 +1,5 @@ commitFormat: angular -title: "testr release" +title: "go-semantic-release release" branch: master: release rc: rc diff --git a/go.mod b/go.mod index eff09c3..dadb3bb 100644 --- a/go.mod +++ b/go.mod @@ -3,19 +3,46 @@ module github.com/Nightapes/go-semantic-release go 1.12 require ( + cloud.google.com/go v0.41.0 // indirect github.com/Masterminds/semver v1.4.2 - github.com/google/go-cmp v0.3.0 // indirect - github.com/google/go-github/v25 v25.1.1 + github.com/coreos/bbolt v1.3.3 // indirect + github.com/coreos/etcd v3.3.13+incompatible // indirect + github.com/coreos/go-semver v0.3.0 // indirect + github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a // indirect + github.com/gliderlabs/ssh v0.2.2 // indirect + github.com/go-kit/kit v0.9.0 // indirect + github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect + github.com/google/go-github/v25 v25.1.3 + github.com/grpc-ecosystem/grpc-gateway v1.9.3 // indirect + github.com/kevinburke/ssh_config v0.0.0-20190630040420-2e50c441276c // indirect + github.com/kisielk/errcheck v1.2.0 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect - github.com/pkg/errors v0.8.1 // indirect + github.com/kr/pty v1.1.8 // indirect + github.com/magiconair/properties v1.8.1 // indirect + github.com/pelletier/go-toml v1.4.0 // indirect + github.com/prometheus/common v0.6.0 // indirect + github.com/prometheus/procfs v0.0.3 // indirect + github.com/rogpeppe/fastuuid v1.1.0 // indirect + github.com/russross/blackfriday v2.0.0+incompatible // indirect github.com/sirupsen/logrus v1.4.2 + github.com/spf13/afero v1.2.2 // indirect github.com/spf13/cobra v0.0.5 - github.com/stretchr/testify v1.3.0 // indirect - golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 // indirect - golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/viper v1.4.0 // indirect + github.com/stretchr/objx v0.2.0 // indirect + github.com/ugorji/go v1.1.7 // indirect + go.etcd.io/bbolt v1.3.3 // indirect + golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 // indirect + golang.org/x/exp v0.0.0-20190627132806-fd42eb6b336f // indirect + golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9 // indirect + golang.org/x/mobile v0.0.0-20190607214518-6fa95d984e88 // indirect + golang.org/x/net v0.0.0-20190628185345-da137c7871d7 // indirect golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 - golang.org/x/sys v0.0.0-20190614160838-b47fdc937951 // indirect - google.golang.org/appengine v1.6.1 // indirect - gopkg.in/src-d/go-git.v4 v4.11.0 + golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb // indirect + golang.org/x/tools v0.0.0-20190703212419-2214986f1668 // indirect + google.golang.org/genproto v0.0.0-20190701230453-710ae3a149df // indirect + google.golang.org/grpc v1.22.0 // indirect + gopkg.in/src-d/go-billy.v4 v4.3.1 // indirect + gopkg.in/src-d/go-git.v4 v4.12.0 gopkg.in/yaml.v2 v2.2.2 ) diff --git a/go.sum b/go.sum index 7ea57ff..578d602 100644 --- a/go.sum +++ b/go.sum @@ -1,39 +1,98 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.41.0/go.mod h1:OauMR7DV8fzvZIl2qg6rkaIhD/vmgk4iwEw/h6ercmg= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dgryski/go-sip13 v0.0.0-20190329191031-25c5027a8c7b/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/emirpasic/gods v1.9.0 h1:rUF4PuzEjMChMiNsVjdI+SyLu7rEqpQ5reNFnhC7oFo= github.com/emirpasic/gods v1.9.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= +github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/gliderlabs/ssh v0.1.3/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-github/v25 v25.1.1 h1:6eW++i/CXcR5GKfYaaJT7oJJtHNU+/iiw55noEPNVao= github.com/google/go-github/v25 v25.1.1/go.mod h1:6z5pC69qHtrPJ0sXPsj4BLnd82b+r6sLB7qcBoRZqpw= +github.com/google/go-github/v25 v25.1.3 h1:Ht4YIQgUh4l4lc80fvGnw60khXysXvlgPxPP8uJG3EA= +github.com/google/go-github/v25 v25.1.3/go.mod h1:6z5pC69qHtrPJ0sXPsj4BLnd82b+r6sLB7qcBoRZqpw= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.3/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= @@ -41,116 +100,261 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e h1:RgQk53JHp/Cjunrr1WlsXSZpqXn+uREuHvUVcK82CV8= github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v0.0.0-20190630040420-2e50c441276c h1:VAx3LRNjVNvjtgO7KFRuT/3aye/0zJvwn01rHSfoolo= +github.com/kevinburke/ssh_config v0.0.0-20190630040420-2e50c441276c/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA= github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/tsdb v0.9.1/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday v2.0.0+incompatible/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/xanzy/ssh-agent v0.2.0 h1:Adglfbi5p9Z0BmK2oKU9nTG+zKfniSfnaMYB+ULd+Ro= github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8= +github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= +github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190627132806-fd42eb6b336f/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190607214518-6fa95d984e88/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190502183928-7f726cade0ab/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9 h1:lkiLiLBHGoH3XnqSLUIaBsilGMUjI+Uy2Xu2JLUtTas= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190614160838-b47fdc937951 h1:ZUgGZ7PSkne6oY+VgAvayrB16owfm9/DKAtgWubzgzU= golang.org/x/sys v0.0.0-20190614160838-b47fdc937951/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624190245-7f2218787638/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190703212419-2214986f1668/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190626174449-989357319d63/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190701230453-710ae3a149df/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/src-d/go-billy.v4 v4.2.1 h1:omN5CrMrMcQ+4I8bJ0wEhOBPanIRWzFC953IiXKdYzo= gopkg.in/src-d/go-billy.v4 v4.2.1/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk= +gopkg.in/src-d/go-billy.v4 v4.3.0/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk= +gopkg.in/src-d/go-billy.v4 v4.3.1 h1:OkK1DmefDy1Z6Veu82wdNj/cLpYORhdX4qdaYCPwc7s= +gopkg.in/src-d/go-billy.v4 v4.3.1/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk= gopkg.in/src-d/go-git-fixtures.v3 v3.1.1 h1:XWW/s5W18RaJpmo1l0IYGqXKuJITWRFuA45iOf1dKJs= gopkg.in/src-d/go-git-fixtures.v3 v3.1.1/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= +gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= gopkg.in/src-d/go-git.v4 v4.11.0 h1:cJwWgJ0DXifrNrXM6RGN1Y2yR60Rr1zQ9Q5DX5S9qgU= gopkg.in/src-d/go-git.v4 v4.11.0/go.mod h1:Vtut8izDyrM8BUVQnzJ+YvmNcem2J89EmfZYCkLokZk= +gopkg.in/src-d/go-git.v4 v4.12.0 h1:CKgvBCJCcdfNnyXPYI4Cp8PaDDAmAPEN0CtfEdEAbd8= +gopkg.in/src-d/go-git.v4 v4.12.0/go.mod h1:zjlNnzc1Wjn43v3Mtii7RVxiReNP0fIu9npcXKzuNp4= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index 89e70ca..fdb6d73 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -115,18 +115,39 @@ func (g Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedCh // UploadAssets uploads specified assets func (g Client) UploadAssets(assets []config.Asset) error { for _, asset := range assets { - file, err := os.Open(asset.Name) - if err != nil { - return err - } + if asset.Compress { + zipName, err := util.ZipFile(g.config.Repo, asset.Name) + if err != nil { + return err + } - _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.User, g.config.Repo, *g.release.ID, &github.UploadOptions{Name: file.Name()}, file) - if err != nil { - return err - } + file, err := os.Open(g.config.Repo + zipName) + defer file.Close() - if resp.StatusCode >= http.StatusBadRequest { - return fmt.Errorf("releaser: github: Could not create release: response statuscode: %s", resp.Status) + _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.User, g.config.Repo, *g.release.ID, &github.UploadOptions{Name: zipName}, file) + if err != nil { + return err + } + + if resp.StatusCode >= http.StatusBadRequest { + return fmt.Errorf("releaser: github: Could not upload asset %s: %s", zipName, resp.Status) + } + + } else { + file, err := os.Open(asset.Name) + if err != nil { + return err + } + defer file.Close() + + _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.User, g.config.Repo, *g.release.ID, &github.UploadOptions{Name: file.Name()}, file) + if err != nil { + return err + } + + if resp.StatusCode >= http.StatusBadRequest { + return fmt.Errorf("releaser: github: Could not upload asset %s: %s", file.Name(), resp.Status) + } } } return nil diff --git a/internal/releaser/releaser.go b/internal/releaser/releaser.go index f5ace38..0ee2662 100644 --- a/internal/releaser/releaser.go +++ b/internal/releaser/releaser.go @@ -40,20 +40,3 @@ func (r *Releasers) GetReleaser() (Releaser, error) { } return nil, fmt.Errorf("could not initialize a releaser from this type: %s", r.config.Release) } - -// func checkIfAssetsExists(assets []config.Asset) error { -// var missingAssets []string -// for _, asset := range assets { - -// if _, err := os.Stat(asset.Name); err != nil { -// missingAssets = append(missingAssets, asset.Name) -// } -// } - -// if len(missingAssets) != 0 { -// return fmt.Errorf("could not find specified Asset: %+v ", assets) -// } - -// return nil - -// } diff --git a/internal/releaser/util/util.go b/internal/releaser/util/util.go index cfbf40b..75cfd66 100644 --- a/internal/releaser/util/util.go +++ b/internal/releaser/util/util.go @@ -1,8 +1,10 @@ package util import ( + "archive/zip" "context" "fmt" + "io" "net/http" "os" "strings" @@ -35,3 +37,47 @@ func GetAccessToken(providerName string) (string, error) { } return token, nil } + +// ZipFile compress given file in zip format +func ZipFile(repository string, file string) (string, error) { + + zipFileName := fmt.Sprintf("%s/%s", strings.TrimSuffix(repository, "/"), file) + zipFile, err := os.Create(zipFileName) + + if err != nil { + return "", err + } + + defer zipFile.Close() + + fileToZip, err := os.Open(file) + if err != nil { + return "", err + } + defer fileToZip.Close() + + fileToZipInfo, err := fileToZip.Stat() + if err != nil { + return "", err + } + + zipWriter := zip.NewWriter(zipFile) + + fileToZipHeader, err := zip.FileInfoHeader(fileToZipInfo) + if err != nil { + return "", err + } + + fileToZipHeader.Name = fileToZipInfo.Name() + + fileToZipWriter, err := zipWriter.CreateHeader(fileToZipHeader) + if err != nil { + return "", err + } + + if _, err = io.Copy(fileToZipWriter, fileToZip); err != nil { + return "", err + } + + return zipFileName, nil +} diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index d9bc9dc..cd6be0c 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -245,5 +245,9 @@ func (s *SemanticRelease) Release(force bool) error { return err } + if err = releaser.UploadAssets(s.config.Assets); err != nil { + return err + } + return nil } From 9ecd47654d370ac6c3c9d3ee2471dde801fbb16a Mon Sep 17 00:00:00 2001 From: fwiedmann Date: Sun, 7 Jul 2019 23:49:08 +0200 Subject: [PATCH 52/77] temp(internal/release): fix golint issues --- internal/releaser/github/github.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index fdb6d73..5eb61c4 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -122,6 +122,9 @@ func (g Client) UploadAssets(assets []config.Asset) error { } file, err := os.Open(g.config.Repo + zipName) + if err != nil { + return err + } defer file.Close() _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.User, g.config.Repo, *g.release.ID, &github.UploadOptions{Name: zipName}, file) From 8f876fa866fa205c1c3b084e06714bbac1756606 Mon Sep 17 00:00:00 2001 From: fwiedmann Date: Tue, 9 Jul 2019 01:43:52 +0200 Subject: [PATCH 53/77] feat(cmd/root): r flag default is now current working dir --- cmd/go-semantic-release/commands/root.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/go-semantic-release/commands/root.go b/cmd/go-semantic-release/commands/root.go index c193476..9583c3f 100644 --- a/cmd/go-semantic-release/commands/root.go +++ b/cmd/go-semantic-release/commands/root.go @@ -32,7 +32,11 @@ func Execute(version string) { } func init() { - rootCmd.PersistentFlags().StringP("repository", "r", "", "Path to repository") + currentDir, err := os.Getwd() + if err != nil { + panic(err) + } + rootCmd.PersistentFlags().StringP("repository", "r", currentDir, "Path to repository") rootCmd.PersistentFlags().StringP("loglevel", "l", "error", "Set loglevel") rootCmd.PersistentFlags().StringP("config", "c", ".release.yml", "Path to config file") rootCmd.PersistentFlags().Bool("no-cache", false, "Ignore cache, don't use in ci build") From 3ad20b2d00607acc9273b7a30169edcc66dfa77f Mon Sep 17 00:00:00 2001 From: fwiedmann Date: Tue, 9 Jul 2019 01:45:16 +0200 Subject: [PATCH 54/77] feat(cmd/zip): add command to zip configured files --- cmd/go-semantic-release/commands/zip.go | 37 +++++++++++++++++++++++++ internal/releaser/util/util.go | 32 ++++++++++++++++++--- pkg/semanticrelease/semantic-release.go | 2 ++ 3 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 cmd/go-semantic-release/commands/zip.go diff --git a/cmd/go-semantic-release/commands/zip.go b/cmd/go-semantic-release/commands/zip.go new file mode 100644 index 0000000..a459c32 --- /dev/null +++ b/cmd/go-semantic-release/commands/zip.go @@ -0,0 +1,37 @@ +package commands + +import ( + "github.com/Nightapes/go-semantic-release/pkg/semanticrelease" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(zipCmd) +} + +var zipCmd = &cobra.Command{ + Use: "zip", + Short: "Zip configured artifact from release config", + RunE: func(cmd *cobra.Command, args []string) error { + config, err := cmd.Flags().GetString("config") + if err != nil { + return err + } + + repository, err := cmd.Flags().GetString("repository") + if err != nil { + return err + } + + s, err := semanticrelease.New(readConfig(config), repository) + if err != nil { + return err + } + + if err = s.ZipFiles(); err != nil { + return err + } + + return nil + }, +} diff --git a/internal/releaser/util/util.go b/internal/releaser/util/util.go index 75cfd66..7c1f548 100644 --- a/internal/releaser/util/util.go +++ b/internal/releaser/util/util.go @@ -9,6 +9,7 @@ import ( "os" "strings" + "github.com/Nightapes/go-semantic-release/pkg/config" log "github.com/sirupsen/logrus" "golang.org/x/oauth2" ) @@ -38,19 +39,41 @@ func GetAccessToken(providerName string) (string, error) { return token, nil } -// ZipFile compress given file in zip format -func ZipFile(repository string, file string) (string, error) { +// PrepareAssets prepare all files before uploading +func PrepareAssets(repository string, assets []config.Asset) ([]*string, error) { + filesToUpload := []*string{} + for _, asset := range assets { + if asset.Compress { + log.Debugf("Asset %s will now be compressed", asset.Name) + log.Debugf("Repo url %s", repository) + zipNameWithPath, err := zipFile(repository, asset.Name) + if err != nil { + return filesToUpload, err + } + filesToUpload = append(filesToUpload, &zipNameWithPath) + } else { + tmpFileName := fmt.Sprintf("%s/%s", repository, asset.Name) + filesToUpload = append(filesToUpload, &tmpFileName) + } + log.Debugf("Add asset %s to files to upload", asset.Name) + } + return filesToUpload, nil +} - zipFileName := fmt.Sprintf("%s/%s", strings.TrimSuffix(repository, "/"), file) +// ZipFile compress given file in zip format +func zipFile(repository string, file string) (string, error) { + + zipFileName := fmt.Sprintf("%s/%s.zip", strings.TrimSuffix(repository, "/"), file) zipFile, err := os.Create(zipFileName) if err != nil { return "", err } + log.Debugf("Created zipfile %s", zipFile.Name()) defer zipFile.Close() - fileToZip, err := os.Open(file) + fileToZip, err := os.Open(repository + "/" + file) if err != nil { return "", err } @@ -62,6 +85,7 @@ func ZipFile(repository string, file string) (string, error) { } zipWriter := zip.NewWriter(zipFile) + defer zipWriter.Close() fileToZipHeader, err := zip.FileInfoHeader(fileToZipInfo) if err != nil { diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index cd6be0c..ec96353 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -251,3 +251,5 @@ func (s *SemanticRelease) Release(force bool) error { return nil } + + if file.Compress { From 9175d6cc49a80df9b5ff32ce53637a28000348e7 Mon Sep 17 00:00:00 2001 From: fwiedmann Date: Tue, 9 Jul 2019 01:46:31 +0200 Subject: [PATCH 55/77] temp(internal/releaser): update interface method Uploadassets --- internal/releaser/github/github.go | 53 +++++++++---------------- internal/releaser/releaser.go | 2 +- pkg/semanticrelease/semantic-release.go | 13 +++++- 3 files changed, 31 insertions(+), 37 deletions(-) diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index 5eb61c4..41e1db0 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -113,45 +113,28 @@ func (g Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedCh } // UploadAssets uploads specified assets -func (g Client) UploadAssets(assets []config.Asset) error { - for _, asset := range assets { - if asset.Compress { - zipName, err := util.ZipFile(g.config.Repo, asset.Name) - if err != nil { - return err - } +func (g Client) UploadAssets(repoDir string, assets []config.Asset) error { + filesToUpload, err := util.PrepareAssets(repoDir, assets) + if err != nil { + return err + } + for _, f := range filesToUpload { - file, err := os.Open(g.config.Repo + zipName) - if err != nil { - return err - } - defer file.Close() + file, err := os.Open(*f) + if err != nil { + return err + } - _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.User, g.config.Repo, *g.release.ID, &github.UploadOptions{Name: zipName}, file) - if err != nil { - return err - } + _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.User, g.config.Repo, *g.release.ID, &github.UploadOptions{Name: ""}, file) + if err != nil { + log.Debug("lol") + return err + } - if resp.StatusCode >= http.StatusBadRequest { - return fmt.Errorf("releaser: github: Could not upload asset %s: %s", zipName, resp.Status) - } - - } else { - file, err := os.Open(asset.Name) - if err != nil { - return err - } - defer file.Close() - - _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.User, g.config.Repo, *g.release.ID, &github.UploadOptions{Name: file.Name()}, file) - if err != nil { - return err - } - - if resp.StatusCode >= http.StatusBadRequest { - return fmt.Errorf("releaser: github: Could not upload asset %s: %s", file.Name(), resp.Status) - } + if resp.StatusCode >= http.StatusBadRequest { + return fmt.Errorf("releaser: github: Could not upload asset %s: %s", file.Name(), resp.Status) } } + return nil } diff --git a/internal/releaser/releaser.go b/internal/releaser/releaser.go index 0ee2662..5d82da3 100644 --- a/internal/releaser/releaser.go +++ b/internal/releaser/releaser.go @@ -19,7 +19,7 @@ type Releasers struct { type Releaser interface { ValidateConfig() error CreateRelease(*shared.ReleaseVersion, *shared.GeneratedChangelog) error - UploadAssets(assets []config.Asset) error + UploadAssets(repoDir string, assets []config.Asset) error GetCommitURL() string GetCompareURL(oldVersion, newVersion string) string } diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index ec96353..99f86d5 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -9,6 +9,7 @@ import ( "github.com/Nightapes/go-semantic-release/internal/changelog" "github.com/Nightapes/go-semantic-release/internal/gitutil" "github.com/Nightapes/go-semantic-release/internal/releaser" + "github.com/Nightapes/go-semantic-release/internal/releaser/util" "github.com/Nightapes/go-semantic-release/internal/shared" "github.com/Nightapes/go-semantic-release/pkg/config" log "github.com/sirupsen/logrus" @@ -245,11 +246,21 @@ func (s *SemanticRelease) Release(force bool) error { return err } - if err = releaser.UploadAssets(s.config.Assets); err != nil { + if err = releaser.UploadAssets(s.repository, s.config.Assets); err != nil { return err } return nil } +// ZipFiles zip files configured in release config +func (s *SemanticRelease) ZipFiles() error { + for _, file := range s.config.Assets { if file.Compress { + if _, err := util.PrepareAssets(s.repository, s.config.Assets); err != nil { + return err + } + } + } + return nil +} From abd251f2eca4cea9cc40dd02412fbd49b7ec1def Mon Sep 17 00:00:00 2001 From: fwiedmann Date: Tue, 9 Jul 2019 18:28:59 +0200 Subject: [PATCH 56/77] feat(internal/pkg/releaser/github): upload all configured files from releaser config --- internal/releaser/github/github.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index 41e1db0..24e2a88 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -56,17 +56,17 @@ func New(c *config.GitHubProvider) (*Client, error) { } //GetCommitURL for github -func (g Client) GetCommitURL() string { +func (g *Client) GetCommitURL() string { return fmt.Sprintf("%s/%s/%s/commit/{{hash}}", g.baseURL, g.config.User, g.config.Repo) } //GetCompareURL for github -func (g Client) GetCompareURL(oldVersion, newVersion string) string { +func (g *Client) GetCompareURL(oldVersion, newVersion string) string { return fmt.Sprintf("%s/%s/%s/compare/%s...%s", g.baseURL, g.config.User, g.config.Repo, oldVersion, newVersion) } //ValidateConfig for github -func (g Client) ValidateConfig() error { +func (g *Client) ValidateConfig() error { log.Debugf("validate GitHub provider config") if g.config.Repo == "" { @@ -82,7 +82,7 @@ func (g Client) ValidateConfig() error { } // CreateRelease creates release on remote -func (g Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error { +func (g *Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error { tag := releaseVersion.Next.Version.String() log.Debugf("create release witth version %s", tag) @@ -113,7 +113,7 @@ func (g Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedCh } // UploadAssets uploads specified assets -func (g Client) UploadAssets(repoDir string, assets []config.Asset) error { +func (g *Client) UploadAssets(repoDir string, assets []config.Asset) error { filesToUpload, err := util.PrepareAssets(repoDir, assets) if err != nil { return err @@ -124,10 +124,10 @@ func (g Client) UploadAssets(repoDir string, assets []config.Asset) error { if err != nil { return err } + fileInfo, _ := file.Stat() - _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.User, g.config.Repo, *g.release.ID, &github.UploadOptions{Name: ""}, file) + _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.User, g.config.Repo, g.release.GetID(), &github.UploadOptions{Name: fileInfo.Name()}, file) if err != nil { - log.Debug("lol") return err } @@ -135,6 +135,5 @@ func (g Client) UploadAssets(repoDir string, assets []config.Asset) error { return fmt.Errorf("releaser: github: Could not upload asset %s: %s", file.Name(), resp.Status) } } - return nil } From 30a215b3e7c9476dc574ac36dc1dc0aa5d8686cd Mon Sep 17 00:00:00 2001 From: fwiedmann Date: Tue, 9 Jul 2019 22:51:12 +0200 Subject: [PATCH 57/77] chore(releaser/github): will not exex upload of assets when no gitreleaser gets inizialized from CreateRelease() --- internal/releaser/github/github.go | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index 24e2a88..560f2bb 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -114,25 +114,27 @@ func (g *Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedC // UploadAssets uploads specified assets func (g *Client) UploadAssets(repoDir string, assets []config.Asset) error { - filesToUpload, err := util.PrepareAssets(repoDir, assets) - if err != nil { - return err - } - for _, f := range filesToUpload { - - file, err := os.Open(*f) + if g.release != nil { + filesToUpload, err := util.PrepareAssets(repoDir, assets) if err != nil { return err } - fileInfo, _ := file.Stat() + for _, f := range filesToUpload { - _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.User, g.config.Repo, g.release.GetID(), &github.UploadOptions{Name: fileInfo.Name()}, file) - if err != nil { - return err - } + file, err := os.Open(*f) + if err != nil { + return err + } + fileInfo, _ := file.Stat() - if resp.StatusCode >= http.StatusBadRequest { - return fmt.Errorf("releaser: github: Could not upload asset %s: %s", file.Name(), resp.Status) + _, resp, err := g.client.Repositories.UploadReleaseAsset(g.context, g.config.User, g.config.Repo, g.release.GetID(), &github.UploadOptions{Name: fileInfo.Name()}, file) + if err != nil { + return err + } + + if resp.StatusCode >= http.StatusBadRequest { + return fmt.Errorf("releaser: github: Could not upload asset %s: %s", file.Name(), resp.Status) + } } } return nil From 09b5ccff808638be45caf3f67b636cc421d7c34d Mon Sep 17 00:00:00 2001 From: fwiedmann Date: Tue, 9 Jul 2019 22:59:52 +0200 Subject: [PATCH 58/77] ci(travis): set loglevel to debug --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 29643a9..9071d5f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ script: - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe -ldflags "-X main.version=`./go-semantic-release next`" ./cmd/go-semantic-release/ after_success: - - ./build/go-semantic-release-temp release + - ./build/go-semantic-release-temp release --loglevel debug branches: except: From 507333f08771a21ad3f7bbb640790d52ae7cda1a Mon Sep 17 00:00:00 2001 From: "svbeisch@gmail.com" Date: Sun, 14 Jul 2019 15:33:16 +0200 Subject: [PATCH 59/77] ci(travis): set loglevel to debug for next version --- .travis.yml | 6 +- go.mod | 31 +---- go.sum | 211 +---------------------------- internal/releaser/github/github.go | 2 +- 4 files changed, 9 insertions(+), 241 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9071d5f..053efa4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,9 +28,9 @@ script: - golangci-lint run ./... - go test -v ./... - go build -o build/go-semantic-release-temp ./cmd/go-semantic-release/ - - echo "Building version `./build/go-semantic-release-temp next`" - - go build -o build/go-semantic-release -ldflags "-X main.version=`./go-semantic-release next`" ./cmd/go-semantic-release/ - - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe -ldflags "-X main.version=`./go-semantic-release next`" ./cmd/go-semantic-release/ + - echo "Building version `./build/go-semantic-release-temp next --loglevel debug`" + - go build -o build/go-semantic-release -ldflags "-X main.version=`./go-semantic-release-temp next`" ./cmd/go-semantic-release/ + - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe -ldflags "-X main.version=`./go-semantic-release-temp next`" ./cmd/go-semantic-release/ after_success: - ./build/go-semantic-release-temp release --loglevel debug diff --git a/go.mod b/go.mod index dadb3bb..1696bb4 100644 --- a/go.mod +++ b/go.mod @@ -3,45 +3,18 @@ module github.com/Nightapes/go-semantic-release go 1.12 require ( - cloud.google.com/go v0.41.0 // indirect github.com/Masterminds/semver v1.4.2 - github.com/coreos/bbolt v1.3.3 // indirect - github.com/coreos/etcd v3.3.13+incompatible // indirect - github.com/coreos/go-semver v0.3.0 // indirect - github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a // indirect github.com/gliderlabs/ssh v0.2.2 // indirect - github.com/go-kit/kit v0.9.0 // indirect - github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect + github.com/google/go-cmp v0.3.0 // indirect github.com/google/go-github/v25 v25.1.3 - github.com/grpc-ecosystem/grpc-gateway v1.9.3 // indirect github.com/kevinburke/ssh_config v0.0.0-20190630040420-2e50c441276c // indirect - github.com/kisielk/errcheck v1.2.0 // indirect - github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect - github.com/kr/pty v1.1.8 // indirect - github.com/magiconair/properties v1.8.1 // indirect - github.com/pelletier/go-toml v1.4.0 // indirect - github.com/prometheus/common v0.6.0 // indirect - github.com/prometheus/procfs v0.0.3 // indirect - github.com/rogpeppe/fastuuid v1.1.0 // indirect - github.com/russross/blackfriday v2.0.0+incompatible // indirect github.com/sirupsen/logrus v1.4.2 - github.com/spf13/afero v1.2.2 // indirect github.com/spf13/cobra v0.0.5 - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/viper v1.4.0 // indirect - github.com/stretchr/objx v0.2.0 // indirect - github.com/ugorji/go v1.1.7 // indirect - go.etcd.io/bbolt v1.3.3 // indirect golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 // indirect - golang.org/x/exp v0.0.0-20190627132806-fd42eb6b336f // indirect - golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9 // indirect - golang.org/x/mobile v0.0.0-20190607214518-6fa95d984e88 // indirect golang.org/x/net v0.0.0-20190628185345-da137c7871d7 // indirect golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb // indirect - golang.org/x/tools v0.0.0-20190703212419-2214986f1668 // indirect - google.golang.org/genproto v0.0.0-20190701230453-710ae3a149df // indirect - google.golang.org/grpc v1.22.0 // indirect + google.golang.org/appengine v1.6.1 // indirect gopkg.in/src-d/go-billy.v4 v4.3.1 // indirect gopkg.in/src-d/go-git.v4 v4.12.0 gopkg.in/yaml.v2 v2.2.2 diff --git a/go.sum b/go.sum index 578d602..5a9a17d 100644 --- a/go.sum +++ b/go.sum @@ -1,98 +1,42 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.41.0/go.mod h1:OauMR7DV8fzvZIl2qg6rkaIhD/vmgk4iwEw/h6ercmg= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= -github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dgryski/go-sip13 v0.0.0-20190329191031-25c5027a8c7b/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/emirpasic/gods v1.9.0 h1:rUF4PuzEjMChMiNsVjdI+SyLu7rEqpQ5reNFnhC7oFo= -github.com/emirpasic/gods v1.9.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.1.1 h1:j3L6gSLQalDETeEg/Jg0mGY0/y/N6zI2xX1978P0Uqw= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/gliderlabs/ssh v0.1.3/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-github/v25 v25.1.1 h1:6eW++i/CXcR5GKfYaaJT7oJJtHNU+/iiw55noEPNVao= -github.com/google/go-github/v25 v25.1.1/go.mod h1:6z5pC69qHtrPJ0sXPsj4BLnd82b+r6sLB7qcBoRZqpw= github.com/google/go-github/v25 v25.1.3 h1:Ht4YIQgUh4l4lc80fvGnw60khXysXvlgPxPP8uJG3EA= github.com/google/go-github/v25 v25.1.3/go.mod h1:6z5pC69qHtrPJ0sXPsj4BLnd82b+r6sLB7qcBoRZqpw= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.3/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= @@ -100,261 +44,112 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e h1:RgQk53JHp/Cjunrr1WlsXSZpqXn+uREuHvUVcK82CV8= github.com/kevinburke/ssh_config v0.0.0-20180830205328-81db2a75821e/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kevinburke/ssh_config v0.0.0-20190630040420-2e50c441276c h1:VAx3LRNjVNvjtgO7KFRuT/3aye/0zJvwn01rHSfoolo= github.com/kevinburke/ssh_config v0.0.0-20190630040420-2e50c441276c/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/pelletier/go-buffruneio v0.2.0 h1:U4t4R6YkofJ5xHm3dJzuRpPZ0mr5MMCoAWooScCR7aA= github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= -github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/prometheus/tsdb v0.9.1/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= -github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday v2.0.0+incompatible/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/xanzy/ssh-agent v0.2.0 h1:Adglfbi5p9Z0BmK2oKU9nTG+zKfniSfnaMYB+ULd+Ro= -github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8= github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= -go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 h1:u+LnwYTOOW7Ukr/fppxEb1Nwz0AtPflrblfvUudpo+I= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXTqk7U7zPQCb+T4rbU9ZEoU= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190627132806-fd42eb6b336f/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190607214518-6fa95d984e88/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190502183928-7f726cade0ab/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6 h1:bjcUS9ztw9kFmmIxJInhon/0Is3p+EHBKNgquIzo1OI= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9 h1:lkiLiLBHGoH3XnqSLUIaBsilGMUjI+Uy2Xu2JLUtTas= golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190614160838-b47fdc937951 h1:ZUgGZ7PSkne6oY+VgAvayrB16owfm9/DKAtgWubzgzU= -golang.org/x/sys v0.0.0-20190614160838-b47fdc937951/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624190245-7f2218787638/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190703212419-2214986f1668/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190626174449-989357319d63/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190701230453-710ae3a149df/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/src-d/go-billy.v4 v4.2.1 h1:omN5CrMrMcQ+4I8bJ0wEhOBPanIRWzFC953IiXKdYzo= -gopkg.in/src-d/go-billy.v4 v4.2.1/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk= gopkg.in/src-d/go-billy.v4 v4.3.0/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk= gopkg.in/src-d/go-billy.v4 v4.3.1 h1:OkK1DmefDy1Z6Veu82wdNj/cLpYORhdX4qdaYCPwc7s= gopkg.in/src-d/go-billy.v4 v4.3.1/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk= -gopkg.in/src-d/go-git-fixtures.v3 v3.1.1 h1:XWW/s5W18RaJpmo1l0IYGqXKuJITWRFuA45iOf1dKJs= -gopkg.in/src-d/go-git-fixtures.v3 v3.1.1/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= +gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg= gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= -gopkg.in/src-d/go-git.v4 v4.11.0 h1:cJwWgJ0DXifrNrXM6RGN1Y2yR60Rr1zQ9Q5DX5S9qgU= -gopkg.in/src-d/go-git.v4 v4.11.0/go.mod h1:Vtut8izDyrM8BUVQnzJ+YvmNcem2J89EmfZYCkLokZk= gopkg.in/src-d/go-git.v4 v4.12.0 h1:CKgvBCJCcdfNnyXPYI4Cp8PaDDAmAPEN0CtfEdEAbd8= gopkg.in/src-d/go-git.v4 v4.12.0/go.mod h1:zjlNnzc1Wjn43v3Mtii7RVxiReNP0fIu9npcXKzuNp4= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/internal/releaser/github/github.go b/internal/releaser/github/github.go index 560f2bb..3f73b95 100644 --- a/internal/releaser/github/github.go +++ b/internal/releaser/github/github.go @@ -85,7 +85,7 @@ func (g *Client) ValidateConfig() error { func (g *Client) CreateRelease(releaseVersion *shared.ReleaseVersion, generatedChangelog *shared.GeneratedChangelog) error { tag := releaseVersion.Next.Version.String() - log.Debugf("create release witth version %s", tag) + log.Debugf("create release with version %s", tag) prerelease := releaseVersion.Next.Version.Prerelease() != "" From 68e7667213adb001120a93cdc0f7543ca9c3f1cc Mon Sep 17 00:00:00 2001 From: "svbeisch@gmail.com" Date: Sun, 14 Jul 2019 15:55:54 +0200 Subject: [PATCH 60/77] ci(travis): disable cache --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 053efa4..f2cd291 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,9 +28,9 @@ script: - golangci-lint run ./... - go test -v ./... - go build -o build/go-semantic-release-temp ./cmd/go-semantic-release/ - - echo "Building version `./build/go-semantic-release-temp next --loglevel debug`" - - go build -o build/go-semantic-release -ldflags "-X main.version=`./go-semantic-release-temp next`" ./cmd/go-semantic-release/ - - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe -ldflags "-X main.version=`./go-semantic-release-temp next`" ./cmd/go-semantic-release/ + - echo "Building version `./build/go-semantic-release-temp next --loglevel debug --no-cache`" + - go build -o build/go-semantic-release -ldflags "-X main.version=`./build/go-semantic-release-temp next`" ./cmd/go-semantic-release/ + - GOOS=windows GOARCH=386 go build -o build/go-semantic-release.exe -ldflags "-X main.version=`./build/go-semantic-release-temp next`" ./cmd/go-semantic-release/ after_success: - ./build/go-semantic-release-temp release --loglevel debug From 24c8f219676b923dbfb6601ce1ac649ce6c11703 Mon Sep 17 00:00:00 2001 From: "svbeisch@gmail.com" Date: Sun, 14 Jul 2019 15:57:12 +0200 Subject: [PATCH 61/77] fix(pkg/semanticrelease): add prerelease for alpha and beta releases --- pkg/semanticrelease/semantic-release.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index 99f86d5..af61e2f 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -108,6 +108,7 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er switch releaseType { case "beta", "alpha": isDraft = true + newVersion = s.incPrerelease(releaseType, newVersion) case "rc": newVersion = s.incPrerelease(releaseType, newVersion) case "release": From e3b54c63b0a96bb391df63e407b20c5be47726c2 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Mon, 15 Jul 2019 21:16:25 +0200 Subject: [PATCH 62/77] fix(cmd): don't print help on error --- cmd/go-semantic-release/commands/root.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/go-semantic-release/commands/root.go b/cmd/go-semantic-release/commands/root.go index 9583c3f..0dcfbe8 100644 --- a/cmd/go-semantic-release/commands/root.go +++ b/cmd/go-semantic-release/commands/root.go @@ -1,7 +1,6 @@ package commands import ( - "fmt" "os" "github.com/Nightapes/go-semantic-release/pkg/config" @@ -18,6 +17,7 @@ var rootCmd = &cobra.Command{ return err } setLoglevel(level) + cmd.SilenceUsage = true return nil }, } @@ -26,7 +26,6 @@ var rootCmd = &cobra.Command{ func Execute(version string) { rootCmd.Version = version if err := rootCmd.Execute(); err != nil { - fmt.Println(err) os.Exit(1) } } From 13afcea8a08b9ab59efb22ef7f0a8bf214ffc6bd Mon Sep 17 00:00:00 2001 From: Nightapes Date: Mon, 15 Jul 2019 21:20:44 +0200 Subject: [PATCH 63/77] feat(ci): check if running on a ci, else skip release --- internal/ci/ci.go | 44 ++++++++++++++ internal/ci/git.go | 38 ++++++++++++ internal/ci/travis.go | 39 ++++++++++++ internal/gitutil/gitutil.go | 2 +- pkg/semanticrelease/semantic-release.go | 81 ++++++++++++++----------- 5 files changed, 169 insertions(+), 35 deletions(-) create mode 100644 internal/ci/ci.go create mode 100644 internal/ci/git.go create mode 100644 internal/ci/travis.go diff --git a/internal/ci/ci.go b/internal/ci/ci.go new file mode 100644 index 0000000..0476413 --- /dev/null +++ b/internal/ci/ci.go @@ -0,0 +1,44 @@ +package ci + +import ( + "fmt" + "github.com/Nightapes/go-semantic-release/internal/gitutil" + log "github.com/sirupsen/logrus" +) + +//ProviderConfig struct +type ProviderConfig struct { + IsPR bool + PR string + PRBranch string + Branch string + Tag string + Commit string + BuildURL string + Service string + Name string +} + +//Service interface +type Service interface { + Detect() (*ProviderConfig, error) +} + +//GetCIProvider get provider +func GetCIProvider(gitUtil *gitutil.GitUtil) (*ProviderConfig, error) { + + services := []Service{ + Travis{}, + Git{gitUtil: gitUtil}, // GIt must be the last option to check + } + + for _, service := range services { + config, err := service.Detect() + if err == nil { + log.Infof("Found CI: %s", config.Name) + return config, nil + } + log.Debugf("%s", err.Error()) + } + return nil, fmt.Errorf("could not find any CI, if running locally set env CI=true") +} diff --git a/internal/ci/git.go b/internal/ci/git.go new file mode 100644 index 0000000..1f13fed --- /dev/null +++ b/internal/ci/git.go @@ -0,0 +1,38 @@ +package ci + +import ( + "fmt" + "github.com/Nightapes/go-semantic-release/internal/gitutil" + "os" +) + +//Git struct +type Git struct { + gitUtil *gitutil.GitUtil +} + +//Detect if on Git +func (t Git) Detect() (*ProviderConfig, error) { + + if _, exists := os.LookupEnv("CI"); !exists { + return nil, fmt.Errorf("running not git only") + } + + hash, err := t.gitUtil.GetHash() + if err != nil { + return nil, err + } + + currentBranch, err := t.gitUtil.GetBranch() + if err != nil { + return nil, err + } + + return &ProviderConfig{ + Service: "Git", + Name: "Git only", + Commit: hash, + Branch: currentBranch, + IsPR: false, + }, nil +} diff --git a/internal/ci/travis.go b/internal/ci/travis.go new file mode 100644 index 0000000..dffd704 --- /dev/null +++ b/internal/ci/travis.go @@ -0,0 +1,39 @@ +package ci + +import ( + "fmt" + log "github.com/sirupsen/logrus" + "os" +) + +//Travis struct +type Travis struct{} + +//Detect if on travis +func (t Travis) Detect() (*ProviderConfig, error) { + + if _, exists := os.LookupEnv("TRAVIS"); !exists { + return nil, fmt.Errorf("not running on travis") + } + + isPR := false + + value := os.Getenv("TRAVIS_PULL_REQUEST") + + if value == "false" { + log.Debugf("TRAVIS_PULL_REQUEST=%s, not running on pr", value) + } else { + isPR = true + } + + return &ProviderConfig{ + Service: "travis", + Name: "Travis CI", + Commit: os.Getenv("TRAVIS_COMMIT"), + Tag: os.Getenv("TRAVIS_TAG"), + BuildURL: os.Getenv("TRAVIS_BUILD_WEB_URL"), + Branch: os.Getenv("TRAVIS_BRANCH"), + IsPR: isPR, + PRBranch: os.Getenv("TRAVIS_PULL_REQUEST_BRANCH"), + }, nil +} diff --git a/internal/gitutil/gitutil.go b/internal/gitutil/gitutil.go index 8e41517..9372e4e 100644 --- a/internal/gitutil/gitutil.go +++ b/internal/gitutil/gitutil.go @@ -100,7 +100,7 @@ func (g *GitUtil) GetLastVersion() (*semver.Version, string, error) { log.Debugf("Add tag %s", p.Name().Short()) tags = append(tags, v) } else { - log.Debugf("Found tag %s, but is not annotated, skip", err.Error()) + log.Debugf("Found tag, but is not annotated, skip") } } else { log.Debugf("Tag %s is not a valid version, skip", p.Name().Short()) diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index af61e2f..a2b3507 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -1,12 +1,14 @@ package semanticrelease import ( + "fmt" "io/ioutil" "strings" "github.com/Masterminds/semver" "github.com/Nightapes/go-semantic-release/internal/analyzer" "github.com/Nightapes/go-semantic-release/internal/changelog" + "github.com/Nightapes/go-semantic-release/internal/ci" "github.com/Nightapes/go-semantic-release/internal/gitutil" "github.com/Nightapes/go-semantic-release/internal/releaser" "github.com/Nightapes/go-semantic-release/internal/releaser/util" @@ -52,14 +54,22 @@ func New(c *config.ReleaseConfig, repository string) (*SemanticRelease, error) { // GetNextVersion from .version or calculate new from commits func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, error) { - hash, err := s.gitutil.GetHash() + provider, err := ci.GetCIProvider(s.gitutil) + if err != nil { - return nil, err + fakeVersion, _ := semver.NewVersion("0.0.0-fake.0") + log.Warnf("Will not calculate version, set fake version. Could not find CI Provider, if running locally, set env CI=true") + return &shared.ReleaseVersion{ + Next: shared.ReleaseVersionEntry{ + Commit: "", + Version: fakeVersion, + }, + }, nil } log.Debugf("Ignore .version file if exits, %t", force) if !force { - releaseVersion, err := s.readFromCache(hash) + releaseVersion, err := s.readFromCache(provider.Commit) if err != nil { return nil, err } @@ -69,22 +79,19 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er } } - currentBranch, err := s.gitutil.GetBranch() - if err != nil { - return nil, err - } - lastVersion, lastVersionHash, err := s.gitutil.GetLastVersion() if err != nil { return nil, err } var newVersion semver.Version + firstRelease := false if lastVersion == nil { defaultVersion, _ := semver.NewVersion("1.0.0") newVersion = *defaultVersion lastVersion = defaultVersion + firstRelease = true } else { newVersion = *lastVersion } @@ -103,8 +110,8 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er result := a.Analyze(commits) isDraft := false for branch, releaseType := range s.config.Branch { - if currentBranch == branch || strings.HasPrefix(currentBranch, branch) { - log.Debugf("Found branch config for branch %s with release type %s", currentBranch, releaseType) + if provider.Branch == branch || strings.HasPrefix(provider.Branch, branch) { + log.Debugf("Found branch config for branch %s with release type %s", provider.Branch, releaseType) switch releaseType { case "beta", "alpha": isDraft = true @@ -112,12 +119,14 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er case "rc": newVersion = s.incPrerelease(releaseType, newVersion) case "release": - if len(result["major"]) > 0 { - newVersion = newVersion.IncMajor() - } else if len(result["minor"]) > 0 { - newVersion = newVersion.IncMinor() - } else if len(result["patch"]) > 0 { - newVersion = newVersion.IncPatch() + if !firstRelease { + if len(result["major"]) > 0 { + newVersion = newVersion.IncMajor() + } else if len(result["minor"]) > 0 { + newVersion = newVersion.IncMinor() + } else if len(result["patch"]) > 0 { + newVersion = newVersion.IncPatch() + } } } } @@ -125,14 +134,14 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er releaseVersion := shared.ReleaseVersion{ Next: shared.ReleaseVersionEntry{ - Commit: hash, + Commit: provider.Commit, Version: &newVersion, }, Last: shared.ReleaseVersionEntry{ Commit: lastVersionHash, Version: lastVersion, }, - Branch: currentBranch, + Branch: provider.Branch, Draft: isDraft, } @@ -152,6 +161,12 @@ func (s *SemanticRelease) SetVersion(version string) error { return err } + provider, err := ci.GetCIProvider(s.gitutil) + + if err != nil { + return fmt.Errorf("will not set version. Could not find CI Provider, if running locally, set env CI=true") + } + lastVersion, lastVersionHash, err := s.gitutil.GetLastVersion() if err != nil { return err @@ -160,26 +175,16 @@ func (s *SemanticRelease) SetVersion(version string) error { lastVersion, _ = semver.NewVersion("1.0.0") } - hash, err := s.gitutil.GetHash() - if err != nil { - return err - } - - currentBranch, err := s.gitutil.GetBranch() - if err != nil { - return err - } - return s.saveToCache(shared.ReleaseVersion{ Next: shared.ReleaseVersionEntry{ - Commit: hash, + Commit: provider.Commit, Version: newVersion, }, Last: shared.ReleaseVersionEntry{ Commit: lastVersionHash, Version: lastVersion, }, - Branch: currentBranch, + Branch: provider.Branch, }) } @@ -211,13 +216,21 @@ func (s *SemanticRelease) WriteChangeLog(changelogContent, file string) error { // Release pusblish release to provider func (s *SemanticRelease) Release(force bool) error { - currentBranch, err := s.gitutil.GetBranch() + + provider, err := ci.GetCIProvider(s.gitutil) + if err != nil { - return err + log.Debugf("Will not perform a new release. Could not find CI Provider") + return nil } - if _, ok := s.config.Branch[currentBranch]; !ok { - log.Debugf("Will not perform a new release. Current %s branch is not configured in release config", currentBranch) + if provider.IsPR { + log.Debugf("Will not perform a new release. This is a pull request") + return nil + } + + if _, ok := s.config.Branch[provider.Branch]; !ok { + log.Debugf("Will not perform a new release. Current %s branch is not configured in release config", provider.Branch) return nil } From c86ad684c604337cbf28f6ae537071ced329dd34 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 16 Jul 2019 20:26:57 +0200 Subject: [PATCH 64/77] test(ci services): add test for travis --- go.mod | 1 + internal/ci/ci.go | 6 +-- internal/ci/ci_test.go | 86 ++++++++++++++++++++++++++++++++++++++++++ internal/ci/git.go | 2 +- internal/ci/travis.go | 5 ++- 5 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 internal/ci/ci_test.go diff --git a/go.mod b/go.mod index 1696bb4..f966aa2 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/kevinburke/ssh_config v0.0.0-20190630040420-2e50c441276c // indirect github.com/sirupsen/logrus v1.4.2 github.com/spf13/cobra v0.0.5 + github.com/stretchr/testify v1.3.0 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 // indirect golang.org/x/net v0.0.0-20190628185345-da137c7871d7 // indirect golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 diff --git a/internal/ci/ci.go b/internal/ci/ci.go index 0476413..52173e5 100644 --- a/internal/ci/ci.go +++ b/internal/ci/ci.go @@ -21,7 +21,7 @@ type ProviderConfig struct { //Service interface type Service interface { - Detect() (*ProviderConfig, error) + detect() (*ProviderConfig, error) } //GetCIProvider get provider @@ -33,12 +33,12 @@ func GetCIProvider(gitUtil *gitutil.GitUtil) (*ProviderConfig, error) { } for _, service := range services { - config, err := service.Detect() + config, err := service.detect() if err == nil { log.Infof("Found CI: %s", config.Name) return config, nil } - log.Debugf("%s", err.Error()) + log.Infof("%s", err.Error()) } return nil, fmt.Errorf("could not find any CI, if running locally set env CI=true") } diff --git a/internal/ci/ci_test.go b/internal/ci/ci_test.go new file mode 100644 index 0000000..38f948f --- /dev/null +++ b/internal/ci/ci_test.go @@ -0,0 +1,86 @@ +package ci_test + +import ( + "testing" + + "github.com/Nightapes/go-semantic-release/internal/ci" + "github.com/Nightapes/go-semantic-release/internal/gitutil" + "github.com/stretchr/testify/assert" + "gopkg.in/src-d/go-git.v4" + "gopkg.in/src-d/go-git.v4/storage/memory" + "os" +) + +func TestSum(t *testing.T) { + testConfigs := []struct { + service string + envs map[string]string + result *ci.ProviderConfig + hasError bool + }{ + { + service: "none", + envs: map[string]string{}, + result: nil, + hasError: true, + }, + // { + // service: "Git", + // envs: map[string]string{ + // "CI": "true", + // }, + // result: &ci.ProviderConfig{IsPR: true, PR: "10", PRBranch: "pr", Branch: "master", Tag: "TAG", Commit: "190bfd6aa60022afd0ef830342cfb07e33c45f37", BuildURL: "https://travis-ci.com/owner/repo/builds/1234", Service: "travis", Name: "Travis CI"}, + // hasError: false, + // }, + { + service: "Travis PR", + envs: map[string]string{ + "TRAVIS": "true", + "TRAVIS_PULL_REQUEST": "10", + "TRAVIS_COMMIT": "190bfd6aa60022afd0ef830342cfb07e33c45f37", + "TRAVIS_TAG": "TAG", + "TRAVIS_BUILD_WEB_URL": "https://travis-ci.com/owner/repo/builds/1234", + "TRAVIS_BRANCH": "master", + "TRAVIS_PULL_REQUEST_BRANCH": "pr", + }, + result: &ci.ProviderConfig{IsPR: true, PR: "10", PRBranch: "pr", Branch: "master", Tag: "TAG", Commit: "190bfd6aa60022afd0ef830342cfb07e33c45f37", BuildURL: "https://travis-ci.com/owner/repo/builds/1234", Service: "travis", Name: "Travis CI"}, + hasError: false, + }, + { + service: "Travis Push", + envs: map[string]string{ + "TRAVIS": "true", + "TRAVIS_PULL_REQUEST": "false", + "TRAVIS_COMMIT": "190bfd6aa60022afd0ef830342cfb07e33c45f37", + "TRAVIS_TAG": "TAG", + "TRAVIS_BUILD_WEB_URL": "https://travis-ci.com/owner/repo/builds/1234", + "TRAVIS_BRANCH": "master", + }, + result: &ci.ProviderConfig{IsPR: false, PR: "", PRBranch: "", Branch: "master", Tag: "TAG", Commit: "190bfd6aa60022afd0ef830342cfb07e33c45f37", BuildURL: "https://travis-ci.com/owner/repo/builds/1234", Service: "travis", Name: "Travis CI"}, + hasError: false, + }, + } + + repository, err := git.Init(memory.NewStorage(), nil) + assert.NoError(t, err, "should open git repository") + + gitUtilInMemory := &gitutil.GitUtil{ + Repository: repository, + } + + for _, config := range testConfigs { + + for key, value := range config.envs { + os.Setenv(key, value) + } + + provider, err := ci.GetCIProvider(gitUtilInMemory) + assert.Equalf(t, config.hasError, err != nil, "Service %s should have error: %t -> %s", config.service, config.hasError, err) + assert.Equalf(t, config.result, provider, "Service %s should have provider", config.service) + + for key, _ := range config.envs { + os.Unsetenv(key) + } + } + +} diff --git a/internal/ci/git.go b/internal/ci/git.go index 1f13fed..a531e86 100644 --- a/internal/ci/git.go +++ b/internal/ci/git.go @@ -12,7 +12,7 @@ type Git struct { } //Detect if on Git -func (t Git) Detect() (*ProviderConfig, error) { +func (t Git) detect() (*ProviderConfig, error) { if _, exists := os.LookupEnv("CI"); !exists { return nil, fmt.Errorf("running not git only") diff --git a/internal/ci/travis.go b/internal/ci/travis.go index dffd704..f069c59 100644 --- a/internal/ci/travis.go +++ b/internal/ci/travis.go @@ -10,7 +10,7 @@ import ( type Travis struct{} //Detect if on travis -func (t Travis) Detect() (*ProviderConfig, error) { +func (t Travis) detect() (*ProviderConfig, error) { if _, exists := os.LookupEnv("TRAVIS"); !exists { return nil, fmt.Errorf("not running on travis") @@ -19,11 +19,13 @@ func (t Travis) Detect() (*ProviderConfig, error) { isPR := false value := os.Getenv("TRAVIS_PULL_REQUEST") + pr := "" if value == "false" { log.Debugf("TRAVIS_PULL_REQUEST=%s, not running on pr", value) } else { isPR = true + pr = value } return &ProviderConfig{ @@ -34,6 +36,7 @@ func (t Travis) Detect() (*ProviderConfig, error) { BuildURL: os.Getenv("TRAVIS_BUILD_WEB_URL"), Branch: os.Getenv("TRAVIS_BRANCH"), IsPR: isPR, + PR: pr, PRBranch: os.Getenv("TRAVIS_PULL_REQUEST_BRANCH"), }, nil } From ab14ab397cff7ceddb751020b7f207acf1ca9aee Mon Sep 17 00:00:00 2001 From: Nightapes Date: Tue, 16 Jul 2019 20:42:40 +0200 Subject: [PATCH 65/77] refactor(ci): improve testing --- internal/ci/ci.go | 19 ++++++++++++++++--- internal/ci/ci_test.go | 12 +----------- internal/ci/git.go | 5 ++--- internal/ci/travis.go | 17 ++++++++--------- pkg/semanticrelease/semantic-release.go | 6 +++--- 5 files changed, 30 insertions(+), 29 deletions(-) diff --git a/internal/ci/ci.go b/internal/ci/ci.go index 52173e5..124e9a9 100644 --- a/internal/ci/ci.go +++ b/internal/ci/ci.go @@ -2,8 +2,11 @@ package ci import ( "fmt" + "github.com/Nightapes/go-semantic-release/internal/gitutil" log "github.com/sirupsen/logrus" + "os" + "strings" ) //ProviderConfig struct @@ -21,11 +24,21 @@ type ProviderConfig struct { //Service interface type Service interface { - detect() (*ProviderConfig, error) + detect(envs map[string]string) (*ProviderConfig, error) +} + +//ReadAllEnvs as a map +func ReadAllEnvs() map[string]string { + envs := map[string]string{} + for _, pair := range os.Environ() { + splitted := strings.SplitN(pair, "=", 2) + envs[splitted[0]] = splitted[1] + } + return envs } //GetCIProvider get provider -func GetCIProvider(gitUtil *gitutil.GitUtil) (*ProviderConfig, error) { +func GetCIProvider(gitUtil *gitutil.GitUtil, envs map[string]string) (*ProviderConfig, error) { services := []Service{ Travis{}, @@ -33,7 +46,7 @@ func GetCIProvider(gitUtil *gitutil.GitUtil) (*ProviderConfig, error) { } for _, service := range services { - config, err := service.detect() + config, err := service.detect(envs) if err == nil { log.Infof("Found CI: %s", config.Name) return config, nil diff --git a/internal/ci/ci_test.go b/internal/ci/ci_test.go index 38f948f..b1e46bb 100644 --- a/internal/ci/ci_test.go +++ b/internal/ci/ci_test.go @@ -8,7 +8,6 @@ import ( "github.com/stretchr/testify/assert" "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/storage/memory" - "os" ) func TestSum(t *testing.T) { @@ -69,18 +68,9 @@ func TestSum(t *testing.T) { } for _, config := range testConfigs { - - for key, value := range config.envs { - os.Setenv(key, value) - } - - provider, err := ci.GetCIProvider(gitUtilInMemory) + provider, err := ci.GetCIProvider(gitUtilInMemory, config.envs) assert.Equalf(t, config.hasError, err != nil, "Service %s should have error: %t -> %s", config.service, config.hasError, err) assert.Equalf(t, config.result, provider, "Service %s should have provider", config.service) - - for key, _ := range config.envs { - os.Unsetenv(key) - } } } diff --git a/internal/ci/git.go b/internal/ci/git.go index a531e86..075cb83 100644 --- a/internal/ci/git.go +++ b/internal/ci/git.go @@ -3,7 +3,6 @@ package ci import ( "fmt" "github.com/Nightapes/go-semantic-release/internal/gitutil" - "os" ) //Git struct @@ -12,9 +11,9 @@ type Git struct { } //Detect if on Git -func (t Git) detect() (*ProviderConfig, error) { +func (t Git) detect(envs map[string]string) (*ProviderConfig, error) { - if _, exists := os.LookupEnv("CI"); !exists { + if _, exists := envs["CI"]; !exists { return nil, fmt.Errorf("running not git only") } diff --git a/internal/ci/travis.go b/internal/ci/travis.go index f069c59..7feed2e 100644 --- a/internal/ci/travis.go +++ b/internal/ci/travis.go @@ -3,22 +3,21 @@ package ci import ( "fmt" log "github.com/sirupsen/logrus" - "os" ) //Travis struct type Travis struct{} //Detect if on travis -func (t Travis) detect() (*ProviderConfig, error) { +func (t Travis) detect(envs map[string]string) (*ProviderConfig, error) { - if _, exists := os.LookupEnv("TRAVIS"); !exists { + if _, exists := envs["TRAVIS"]; !exists { return nil, fmt.Errorf("not running on travis") } isPR := false - value := os.Getenv("TRAVIS_PULL_REQUEST") + value := envs["TRAVIS_PULL_REQUEST"] pr := "" if value == "false" { @@ -31,12 +30,12 @@ func (t Travis) detect() (*ProviderConfig, error) { return &ProviderConfig{ Service: "travis", Name: "Travis CI", - Commit: os.Getenv("TRAVIS_COMMIT"), - Tag: os.Getenv("TRAVIS_TAG"), - BuildURL: os.Getenv("TRAVIS_BUILD_WEB_URL"), - Branch: os.Getenv("TRAVIS_BRANCH"), + Commit: envs["TRAVIS_COMMIT"], + Tag: envs["TRAVIS_TAG"], + BuildURL: envs["TRAVIS_BUILD_WEB_URL"], + Branch: envs["TRAVIS_BRANCH"], IsPR: isPR, PR: pr, - PRBranch: os.Getenv("TRAVIS_PULL_REQUEST_BRANCH"), + PRBranch: envs["TRAVIS_PULL_REQUEST_BRANCH"], }, nil } diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index a2b3507..b5a96b1 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -54,7 +54,7 @@ func New(c *config.ReleaseConfig, repository string) (*SemanticRelease, error) { // GetNextVersion from .version or calculate new from commits func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, error) { - provider, err := ci.GetCIProvider(s.gitutil) + provider, err := ci.GetCIProvider(s.gitutil, ci.ReadAllEnvs()) if err != nil { fakeVersion, _ := semver.NewVersion("0.0.0-fake.0") @@ -161,7 +161,7 @@ func (s *SemanticRelease) SetVersion(version string) error { return err } - provider, err := ci.GetCIProvider(s.gitutil) + provider, err := ci.GetCIProvider(s.gitutil, ci.ReadAllEnvs()) if err != nil { return fmt.Errorf("will not set version. Could not find CI Provider, if running locally, set env CI=true") @@ -217,7 +217,7 @@ func (s *SemanticRelease) WriteChangeLog(changelogContent, file string) error { // Release pusblish release to provider func (s *SemanticRelease) Release(force bool) error { - provider, err := ci.GetCIProvider(s.gitutil) + provider, err := ci.GetCIProvider(s.gitutil, ci.ReadAllEnvs()) if err != nil { log.Debugf("Will not perform a new release. Could not find CI Provider") From 69db52e5b10d9af8e86be66a3407825fb2f793c2 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Sun, 21 Jul 2019 15:06:49 +0200 Subject: [PATCH 66/77] feat(internal/changelog): add breaking changes to changelog --- internal/changelog/changelog.go | 57 +++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/internal/changelog/changelog.go b/internal/changelog/changelog.go index f1a9319..e00a29f 100644 --- a/internal/changelog/changelog.go +++ b/internal/changelog/changelog.go @@ -15,6 +15,14 @@ import ( const defaultChangelogTitle string = `v{{.Version}} ({{.Now.Format "2006-01-02"}})` const defaultChangelog string = `# v{{$.Version}} ({{.Now.Format "2006-01-02"}}) +{{ range $index,$commit := .BreakingChanges -}} +{{ if eq $index 0 }} +## BREAKING CHANGES +{{ end}} +* **{{$.Backtick}}{{$commit.Scope}}{{$.Backtick}}** {{$commit.ParsedBreakingChangeMessage}} +introduced by commit: +{{$commit.ParsedMessage}} {{if $.HasURL}} ([{{ printf "%.7s" $commit.Commit.Hash}}]({{ replace $.URL "{{hash}}" $commit.Commit.Hash}})) {{end}} +{{ end -}} {{ range $key := .Order }} {{ $commits := index $.Commits $key}} {{if $commits -}} ### {{ $key }} @@ -26,33 +34,37 @@ const defaultChangelog string = `# v{{$.Version}} ({{.Now.Format "2006-01-02"}}) ` type changelogContent struct { - Commits map[string][]analyzer.AnalyzedCommit - Order []string - Version string - Now time.Time - Backtick string - HasURL bool - URL string + Commits map[string][]analyzer.AnalyzedCommit + BreakingChanges []analyzer.AnalyzedCommit + Order []string + Version string + Now time.Time + Backtick string + HasURL bool + URL string } //Changelog struct type Changelog struct { - config *config.ReleaseConfig - rules []analyzer.Rule + config *config.ReleaseConfig + rules []analyzer.Rule + releaseTime time.Time } //New Changelog struct for generating changelog from commits -func New(config *config.ReleaseConfig, rules []analyzer.Rule) *Changelog { +func New(config *config.ReleaseConfig, rules []analyzer.Rule, releaseTime time.Time) *Changelog { return &Changelog{ - config: config, - rules: rules, + config: config, + rules: rules, + releaseTime: releaseTime, } } // GenerateChanglog from given commits -func (c *Changelog) GenerateChanglog(templateConfig shared.ChangelogTemplateConfig, analyzedCommits map[string][]analyzer.AnalyzedCommit) (*shared.GeneratedChangelog, error) { +func (c *Changelog) GenerateChanglog(templateConfig shared.ChangelogTemplateConfig, analyzedCommits map[analyzer.Release][]analyzer.AnalyzedCommit) (*shared.GeneratedChangelog, error) { commitsPerScope := map[string][]analyzer.AnalyzedCommit{} + commitsBreakingChange := []analyzer.AnalyzedCommit{} order := make([]string, 0) for _, rule := range c.rules { @@ -65,6 +77,10 @@ func (c *Changelog) GenerateChanglog(templateConfig shared.ChangelogTemplateConf for _, commits := range analyzedCommits { for _, commit := range commits { if commit.Print { + if commit.ParsedBreakingChangeMessage != "" { + commitsBreakingChange = append(commitsBreakingChange, commit) + continue + } if _, ok := commitsPerScope[commit.TagString]; !ok { commitsPerScope[commit.TagString] = make([]analyzer.AnalyzedCommit, 0) } @@ -74,13 +90,14 @@ func (c *Changelog) GenerateChanglog(templateConfig shared.ChangelogTemplateConf } changelogContent := changelogContent{ - Version: templateConfig.Version, - Commits: commitsPerScope, - Now: time.Now(), - Backtick: "`", - Order: order, - HasURL: templateConfig.CommitURL != "", - URL: templateConfig.CommitURL, + Version: templateConfig.Version, + Commits: commitsPerScope, + Now: c.releaseTime, + BreakingChanges: commitsBreakingChange, + Backtick: "`", + Order: order, + HasURL: templateConfig.CommitURL != "", + URL: templateConfig.CommitURL, } title, err := generateTemplate(defaultChangelogTitle, changelogContent) From 791983faae671303a63b9df91a07ca17b36d476e Mon Sep 17 00:00:00 2001 From: Nightapes Date: Sun, 21 Jul 2019 15:07:13 +0200 Subject: [PATCH 67/77] test(*): add unit tests --- .gitignore | 1 + cmd/go-semantic-release/commands/ci.go | 37 +++++ go.mod | 2 +- internal/analyzer/analyzer.go | 14 +- internal/analyzer/analyzer_test.go | 16 +++ internal/analyzer/angular.go | 8 +- internal/analyzer/angular_test.go | 173 ++++++++++++++++++++++++ internal/cache/cache_test.go | 70 ++++++++++ internal/changelog/changelog_test.go | 120 ++++++++++++++++ internal/ci/ci_test.go | 58 +++++--- internal/ci/git.go | 2 +- pkg/semanticrelease/semantic-release.go | 3 +- 12 files changed, 477 insertions(+), 27 deletions(-) create mode 100644 cmd/go-semantic-release/commands/ci.go create mode 100644 internal/analyzer/analyzer_test.go create mode 100644 internal/analyzer/angular_test.go create mode 100644 internal/cache/cache_test.go create mode 100644 internal/changelog/changelog_test.go diff --git a/.gitignore b/.gitignore index 068d872..e623bb9 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ go-semantic-release .version .vscode/settings.json CHANGELOG.md +cover.html diff --git a/cmd/go-semantic-release/commands/ci.go b/cmd/go-semantic-release/commands/ci.go new file mode 100644 index 0000000..8ff26dd --- /dev/null +++ b/cmd/go-semantic-release/commands/ci.go @@ -0,0 +1,37 @@ +package commands + +import ( + "github.com/Nightapes/go-semantic-release/internal/ci" + "github.com/Nightapes/go-semantic-release/internal/gitutil" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(ciCmd) +} + +var ciCmd = &cobra.Command{ + Use: "ci", + Short: "ci configured artifact from release config", + RunE: func(cmd *cobra.Command, args []string) error { + + repository, err := cmd.Flags().GetString("repository") + if err != nil { + return err + } + + util, err := gitutil.New(repository) + if err != nil { + return err + } + + config, err := ci.GetCIProvider(util, ci.ReadAllEnvs()) + if err != nil { + return err + } + log.Infof("Found ci %v", config) + + return nil + }, +} diff --git a/go.mod b/go.mod index f966aa2..6d9f669 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb // indirect google.golang.org/appengine v1.6.1 // indirect - gopkg.in/src-d/go-billy.v4 v4.3.1 // indirect + gopkg.in/src-d/go-billy.v4 v4.3.1 gopkg.in/src-d/go-git.v4 v4.12.0 gopkg.in/yaml.v2 v2.2.2 ) diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go index 7f1f21f..8e6d1be 100644 --- a/internal/analyzer/analyzer.go +++ b/internal/analyzer/analyzer.go @@ -15,11 +15,17 @@ type Analyzer struct { Config config.ChangelogConfig } +//Release types, like major +type Release string + +//Scope of the commit, like feat, fix,.. +type Scope string + //Rule for commits type Rule struct { Tag string TagString string - Release string + Release Release Changelog bool } @@ -32,7 +38,7 @@ type analyzeCommit interface { type AnalyzedCommit struct { Commit gitutil.Commit ParsedMessage string - Scope string + Scope Scope ParsedBreakingChangeMessage string Tag string TagString string @@ -62,9 +68,9 @@ func (a *Analyzer) GetRules() []Rule { } // Analyze commits and return commits splitted by major,minor,patch -func (a *Analyzer) Analyze(commits []gitutil.Commit) map[string][]AnalyzedCommit { +func (a *Analyzer) Analyze(commits []gitutil.Commit) map[Release][]AnalyzedCommit { - analyzedCommits := make(map[string][]AnalyzedCommit) + analyzedCommits := make(map[Release][]AnalyzedCommit) analyzedCommits["major"] = make([]AnalyzedCommit, 0) analyzedCommits["minor"] = make([]AnalyzedCommit, 0) analyzedCommits["patch"] = make([]AnalyzedCommit, 0) diff --git a/internal/analyzer/analyzer_test.go b/internal/analyzer/analyzer_test.go new file mode 100644 index 0000000..0002a73 --- /dev/null +++ b/internal/analyzer/analyzer_test.go @@ -0,0 +1,16 @@ +package analyzer_test + +import ( + "testing" + + "github.com/Nightapes/go-semantic-release/internal/analyzer" + "github.com/Nightapes/go-semantic-release/pkg/config" + "github.com/stretchr/testify/assert" +) + +func TestAnalyzer(t *testing.T) { + + _, err := analyzer.New("unknown", config.ChangelogConfig{}) + assert.Error(t, err) + +} diff --git a/internal/analyzer/angular.go b/internal/analyzer/angular.go index 391085c..47fe6d2 100644 --- a/internal/analyzer/angular.go +++ b/internal/analyzer/angular.go @@ -89,19 +89,19 @@ func (a *angular) analyze(commit gitutil.Commit, rule Rule) (AnalyzedCommit, boo if len(matches) >= 1 { if len(matches[0]) >= 3 { - analyzed.Scope = matches[0][2] + analyzed.Scope = Scope(matches[0][2]) message := strings.Join(matches[0][3:], "") if !strings.Contains(message, "BREAKING CHANGE:") { - analyzed.ParsedMessage = message + analyzed.ParsedMessage = strings.Trim(message, " ") log.Tracef("%s: found %s", commit.Message, rule.Tag) return analyzed, false, nil } breakingChange := strings.SplitN(message, "BREAKING CHANGE:", 2) - analyzed.ParsedMessage = breakingChange[0] - analyzed.ParsedBreakingChangeMessage = breakingChange[1] + analyzed.ParsedMessage = strings.Trim(breakingChange[0], " ") + analyzed.ParsedBreakingChangeMessage = strings.Trim(breakingChange[1], " ") log.Tracef(" %s, BREAKING CHANGE found", commit.Message) return analyzed, true, nil diff --git a/internal/analyzer/angular_test.go b/internal/analyzer/angular_test.go new file mode 100644 index 0000000..c49b046 --- /dev/null +++ b/internal/analyzer/angular_test.go @@ -0,0 +1,173 @@ +package analyzer_test + +import ( + "testing" + + "github.com/Nightapes/go-semantic-release/internal/analyzer" + "github.com/Nightapes/go-semantic-release/internal/gitutil" + "github.com/Nightapes/go-semantic-release/pkg/config" + "github.com/stretchr/testify/assert" +) + +func TestAngular(t *testing.T) { + + testConfigs := []struct { + testCase string + commits []gitutil.Commit + analyzedCommits map[analyzer.Release][]analyzer.AnalyzedCommit + }{ + { + testCase: "feat", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "minor": []analyzer.AnalyzedCommit{ + analyzer.AnalyzedCommit{ + Commit: gitutil.Commit{ + Message: "feat(internal/changelog): my first commit", + Author: "me", + Hash: "12345667", + }, + Scope: "internal/changelog", + ParsedMessage: "my first commit", + Tag: "feat", + TagString: "Features", + Print: true, + }, + }, + "major": []analyzer.AnalyzedCommit{}, + "patch": []analyzer.AnalyzedCommit{}, + "none": []analyzer.AnalyzedCommit{}, + }, + commits: []gitutil.Commit{ + gitutil.Commit{ + Message: "feat(internal/changelog): my first commit", + Author: "me", + Hash: "12345667", + }, + }, + }, + { + testCase: "feat breaking change", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "minor": []analyzer.AnalyzedCommit{ + analyzer.AnalyzedCommit{ + Commit: gitutil.Commit{ + Message: "feat(internal/changelog): my first commit", + Author: "me", + Hash: "12345667", + }, + Scope: "internal/changelog", + ParsedMessage: "my first commit", + Tag: "feat", + TagString: "Features", + Print: true, + }, + }, + "major": []analyzer.AnalyzedCommit{ + analyzer.AnalyzedCommit{ + Commit: gitutil.Commit{ + Message: "feat(internal/changelog): my first break BREAKING CHANGE: change api to v2", + Author: "me", + Hash: "12345668", + }, + Scope: "internal/changelog", + ParsedMessage: "my first break", + Tag: "feat", + TagString: "Features", + Print: true, + ParsedBreakingChangeMessage: "change api to v2", + }, + }, + "patch": []analyzer.AnalyzedCommit{}, + "none": []analyzer.AnalyzedCommit{}, + }, + commits: []gitutil.Commit{ + gitutil.Commit{ + Message: "feat(internal/changelog): my first commit", + Author: "me", + Hash: "12345667", + }, + gitutil.Commit{ + Message: "feat(internal/changelog): my first break BREAKING CHANGE: change api to v2", + Author: "me", + Hash: "12345668", + }, + }, + }, + { + testCase: "invalid", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "minor": []analyzer.AnalyzedCommit{}, + "major": []analyzer.AnalyzedCommit{}, + "patch": []analyzer.AnalyzedCommit{}, + "none": []analyzer.AnalyzedCommit{}, + }, + commits: []gitutil.Commit{ + gitutil.Commit{ + Message: "internal/changelog: my first commit", + Author: "me", + Hash: "12345667", + }, + }, + }, + { + testCase: "feat and build", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "minor": []analyzer.AnalyzedCommit{ + analyzer.AnalyzedCommit{ + Commit: gitutil.Commit{ + Message: "feat(internal/changelog): my first commit", + Author: "me", + Hash: "12345667", + }, + Scope: "internal/changelog", + ParsedMessage: "my first commit", + Tag: "feat", + TagString: "Features", + Print: true, + }, + }, + "none": []analyzer.AnalyzedCommit{ + analyzer.AnalyzedCommit{ + Commit: gitutil.Commit{ + Message: "build(internal/changelog): my first build", + Author: "me", + Hash: "12345668", + }, + Scope: "internal/changelog", + ParsedMessage: "my first build", + Tag: "build", + TagString: "Changes to CI/CD", + Print: false, + ParsedBreakingChangeMessage: "", + }, + }, + "patch": []analyzer.AnalyzedCommit{}, + "major": []analyzer.AnalyzedCommit{}, + }, + commits: []gitutil.Commit{ + gitutil.Commit{ + Message: "feat(internal/changelog): my first commit", + Author: "me", + Hash: "12345667", + }, + gitutil.Commit{ + Message: "build(internal/changelog): my first build", + Author: "me", + Hash: "12345668", + }, + }, + }, + } + + angular, err := analyzer.New("angular", config.ChangelogConfig{}) + assert.NoError(t, err) + + for _, test := range testConfigs { + analyzedCommits := angular.Analyze(test.commits) + assert.Equalf(t, test.analyzedCommits["major"], analyzedCommits["major"], "Testcase %s should have major commits", test.testCase) + assert.Equalf(t, test.analyzedCommits["minor"], analyzedCommits["minor"], "Testcase %s should have minor commits", test.testCase) + assert.Equalf(t, test.analyzedCommits["patch"], analyzedCommits["patch"], "Testcase %s should have patch commits", test.testCase) + assert.Equalf(t, test.analyzedCommits["none"], analyzedCommits["none"], "Testcase %s should have none commits", test.testCase) + } + +} diff --git a/internal/cache/cache_test.go b/internal/cache/cache_test.go new file mode 100644 index 0000000..7a7b8b2 --- /dev/null +++ b/internal/cache/cache_test.go @@ -0,0 +1,70 @@ +package cache_test + +import ( + "testing" + + "github.com/Nightapes/go-semantic-release/internal/cache" + "github.com/stretchr/testify/assert" + "io/ioutil" + "os" + "path" +) + +func TestReadCacheNotFound(t *testing.T) { + + _, err := cache.Read("notfound/dir") + assert.Errorf(t, err, "Read non exsiting file") + +} + +func TestReadCacheInvalidContent(t *testing.T) { + + dir, err := ioutil.TempDir("", "prefix") + assert.NoError(t, err) + defer os.RemoveAll(dir) + + completePath := path.Join(path.Dir(dir), ".version") + brokenContent := []byte("hello broken\ngo: lang\n") + ioutil.WriteFile(completePath, brokenContent, 0644) + + _, readError := cache.Read(dir) + assert.Errorf(t, readError, "Should give error, when broken content") + +} + +func TestWriteAndReadCache(t *testing.T) { + + dir, err := ioutil.TempDir("", "prefix") + + assert.NoError(t, err) + + content := cache.ReleaseVersion{ + Last: cache.ReleaseVersionEntry{ + Commit: "12345", + Version: "1.0.0", + }, + Next: cache.ReleaseVersionEntry{ + Commit: "12346", + Version: "1.1.0", + }, + Branch: "master", + Draft: true, + } + + defer os.RemoveAll(dir) + + writeError := cache.Write(dir, content) + assert.NoErrorf(t, writeError, "Should write file") + result, readError := cache.Read(dir) + assert.NoErrorf(t, readError, "Should read file") + + assert.Equal(t, &content, result) + +} + +func TestWriteNotFound(t *testing.T) { + + err := cache.Write("notfound/dir", cache.ReleaseVersion{}) + assert.Errorf(t, err, "Write non exsiting file") + +} diff --git a/internal/changelog/changelog_test.go b/internal/changelog/changelog_test.go new file mode 100644 index 0000000..b4a473a --- /dev/null +++ b/internal/changelog/changelog_test.go @@ -0,0 +1,120 @@ +package changelog_test + +import ( + "testing" + + "github.com/Nightapes/go-semantic-release/internal/analyzer" + "github.com/Nightapes/go-semantic-release/internal/changelog" + "github.com/Nightapes/go-semantic-release/internal/gitutil" + "github.com/Nightapes/go-semantic-release/internal/shared" + "github.com/Nightapes/go-semantic-release/pkg/config" + "github.com/stretchr/testify/assert" + "time" +) + +func TestChangelog(t *testing.T) { + + templateConfig := shared.ChangelogTemplateConfig{ + CommitURL: "https://commit.url", + CompareURL: "https://compare.url", + Hash: "hash", + Version: "1.0.0", + } + + testConfigs := []struct { + testCase string + analyzedCommits map[analyzer.Release][]analyzer.AnalyzedCommit + result *shared.GeneratedChangelog + hasError bool + }{ + { + testCase: "feat", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "minor": []analyzer.AnalyzedCommit{ + analyzer.AnalyzedCommit{ + Commit: gitutil.Commit{ + Message: "feat(test): my first commit", + Author: "me", + Hash: "12345667", + }, + Scope: "internal/changelog", + ParsedMessage: "my first commit", + Tag: "feat", + TagString: "Features", + Print: true, + }, + }, + }, + result: &shared.GeneratedChangelog{ + Title: "v1.0.0 (2019-07-19)", + Content: "# v1.0.0 (2019-07-19)\n\n ### Features\n* **`internal/changelog`** my first commit ([1234566](https://commit.url)) \n\n ", + }, + hasError: false, + }, + { + testCase: "feat breaking change", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "minor": []analyzer.AnalyzedCommit{ + analyzer.AnalyzedCommit{ + Commit: gitutil.Commit{ + Message: "feat(test): my first commit", + Author: "me", + Hash: "12345667", + }, + Scope: "internal/changelog", + ParsedMessage: "my first commit", + Tag: "feat", + TagString: "Features", + Print: true, + }, + analyzer.AnalyzedCommit{ + Commit: gitutil.Commit{ + Message: "feat(test): my first break: BREAKING CHANGE: change api to v2", + Author: "me", + Hash: "12345668", + }, + Scope: "internal/changelog", + ParsedMessage: "my first break", + Tag: "feat", + TagString: "Features", + Print: true, + ParsedBreakingChangeMessage: "change api to v2", + }, + }, + }, + result: &shared.GeneratedChangelog{ + Title: "v1.0.0 (2019-07-19)", + Content: "# v1.0.0 (2019-07-19)\n\n## BREAKING CHANGES\n\n* **`internal/changelog`** change api to v2 \nintroduced by commit: \nmy first break ([1234566](https://commit.url)) \n\n ### Features\n* **`internal/changelog`** my first commit ([1234566](https://commit.url)) \n\n ", + }, + hasError: false, + }, + } + + cl := changelog.New(&config.ReleaseConfig{}, []analyzer.Rule{ + { + Tag: "feat", + TagString: "Features", + Release: "minor", + Changelog: true, + }, + { + Tag: "fix", + TagString: "Bug fixes", + Release: "patch", + Changelog: true, + }, + { + Tag: "build", + TagString: "Build", + Release: "none", + Changelog: false, + }, + }, time.Date(2019, 7, 19, 0, 0, 0, 0, time.UTC)) + + for _, config := range testConfigs { + generatedChangelog, err := cl.GenerateChanglog(templateConfig, config.analyzedCommits) + assert.Equalf(t, config.hasError, err != nil, "Testcase %s should have error: %t -> %s", config.testCase, config.hasError, err) + assert.Equalf(t, config.result, generatedChangelog, "Testcase %s should have generated changelog", config.testCase) + } + +} diff --git a/internal/ci/ci_test.go b/internal/ci/ci_test.go index b1e46bb..99205b0 100644 --- a/internal/ci/ci_test.go +++ b/internal/ci/ci_test.go @@ -1,16 +1,49 @@ package ci_test import ( + "fmt" "testing" + "time" "github.com/Nightapes/go-semantic-release/internal/ci" "github.com/Nightapes/go-semantic-release/internal/gitutil" "github.com/stretchr/testify/assert" + "gopkg.in/src-d/go-billy.v4/memfs" "gopkg.in/src-d/go-git.v4" + "gopkg.in/src-d/go-git.v4/plumbing/object" "gopkg.in/src-d/go-git.v4/storage/memory" ) -func TestSum(t *testing.T) { +func TestCi(t *testing.T) { + + fs := memfs.New() + + repository, err := git.Init(memory.NewStorage(), fs) + assert.NoError(t, err, "should open git repository") + + file, err := fs.Create("README.md") + assert.NoError(t, err, "should create file") + + w, err := repository.Worktree() + assert.NoError(t, err, "should get worktree") + + w.Add(file.Name()) + + status, err := w.Status() + fmt.Println(status) + + gitUtilInMemory := &gitutil.GitUtil{ + Repository: repository, + } + + newCommit, err := w.Commit("fix(test): add a commit", &git.CommitOptions{ + Author: &object.Signature{ + Name: "John Doe", + Email: "john@doe.org", + When: time.Now(), + }, + }) + testConfigs := []struct { service string envs map[string]string @@ -23,14 +56,14 @@ func TestSum(t *testing.T) { result: nil, hasError: true, }, - // { - // service: "Git", - // envs: map[string]string{ - // "CI": "true", - // }, - // result: &ci.ProviderConfig{IsPR: true, PR: "10", PRBranch: "pr", Branch: "master", Tag: "TAG", Commit: "190bfd6aa60022afd0ef830342cfb07e33c45f37", BuildURL: "https://travis-ci.com/owner/repo/builds/1234", Service: "travis", Name: "Travis CI"}, - // hasError: false, - // }, + { + service: "Git", + envs: map[string]string{ + "CI": "true", + }, + result: &ci.ProviderConfig{IsPR: false, PR: "", PRBranch: "", Branch: "master", Tag: "", Commit: newCommit.String(), BuildURL: "", Service: "git", Name: "Git only"}, + hasError: false, + }, { service: "Travis PR", envs: map[string]string{ @@ -60,13 +93,6 @@ func TestSum(t *testing.T) { }, } - repository, err := git.Init(memory.NewStorage(), nil) - assert.NoError(t, err, "should open git repository") - - gitUtilInMemory := &gitutil.GitUtil{ - Repository: repository, - } - for _, config := range testConfigs { provider, err := ci.GetCIProvider(gitUtilInMemory, config.envs) assert.Equalf(t, config.hasError, err != nil, "Service %s should have error: %t -> %s", config.service, config.hasError, err) diff --git a/internal/ci/git.go b/internal/ci/git.go index 075cb83..7f814a1 100644 --- a/internal/ci/git.go +++ b/internal/ci/git.go @@ -28,7 +28,7 @@ func (t Git) detect(envs map[string]string) (*ProviderConfig, error) { } return &ProviderConfig{ - Service: "Git", + Service: "git", Name: "Git only", Commit: hash, Branch: currentBranch, diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index b5a96b1..979ba2b 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -4,6 +4,7 @@ import ( "fmt" "io/ioutil" "strings" + "time" "github.com/Masterminds/semver" "github.com/Nightapes/go-semantic-release/internal/analyzer" @@ -199,7 +200,7 @@ func (s *SemanticRelease) GetChangelog(releaseVersion *shared.ReleaseVersion) (* log.Debugf("Found %d commits till last release", len(commits)) - c := changelog.New(s.config, s.analyzer.GetRules()) + c := changelog.New(s.config, s.analyzer.GetRules(), time.Now()) return c.GenerateChanglog(shared.ChangelogTemplateConfig{ Version: releaseVersion.Next.Version.String(), Hash: releaseVersion.Last.Commit, From 409b260eb7b301df0645a772072a41888663d757 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Sun, 21 Jul 2019 15:10:18 +0200 Subject: [PATCH 68/77] refactor(cmd): remove unused ci testing command --- cmd/go-semantic-release/commands/ci.go | 37 -------------------------- 1 file changed, 37 deletions(-) delete mode 100644 cmd/go-semantic-release/commands/ci.go diff --git a/cmd/go-semantic-release/commands/ci.go b/cmd/go-semantic-release/commands/ci.go deleted file mode 100644 index 8ff26dd..0000000 --- a/cmd/go-semantic-release/commands/ci.go +++ /dev/null @@ -1,37 +0,0 @@ -package commands - -import ( - "github.com/Nightapes/go-semantic-release/internal/ci" - "github.com/Nightapes/go-semantic-release/internal/gitutil" - log "github.com/sirupsen/logrus" - "github.com/spf13/cobra" -) - -func init() { - rootCmd.AddCommand(ciCmd) -} - -var ciCmd = &cobra.Command{ - Use: "ci", - Short: "ci configured artifact from release config", - RunE: func(cmd *cobra.Command, args []string) error { - - repository, err := cmd.Flags().GetString("repository") - if err != nil { - return err - } - - util, err := gitutil.New(repository) - if err != nil { - return err - } - - config, err := ci.GetCIProvider(util, ci.ReadAllEnvs()) - if err != nil { - return err - } - log.Infof("Found ci %v", config) - - return nil - }, -} From 58f2ebb6d03100207dde5e1f609a7e65bd25b46f Mon Sep 17 00:00:00 2001 From: Nightapes Date: Sun, 21 Jul 2019 15:15:01 +0200 Subject: [PATCH 69/77] style(internal/*): fix lint issues --- internal/cache/cache_test.go | 3 ++- internal/ci/ci_test.go | 8 +++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/internal/cache/cache_test.go b/internal/cache/cache_test.go index 7a7b8b2..3ca28b0 100644 --- a/internal/cache/cache_test.go +++ b/internal/cache/cache_test.go @@ -25,7 +25,8 @@ func TestReadCacheInvalidContent(t *testing.T) { completePath := path.Join(path.Dir(dir), ".version") brokenContent := []byte("hello broken\ngo: lang\n") - ioutil.WriteFile(completePath, brokenContent, 0644) + err = ioutil.WriteFile(completePath, brokenContent, 0644) + assert.NoError(t, err) _, readError := cache.Read(dir) assert.Errorf(t, readError, "Should give error, when broken content") diff --git a/internal/ci/ci_test.go b/internal/ci/ci_test.go index 99205b0..38a24a1 100644 --- a/internal/ci/ci_test.go +++ b/internal/ci/ci_test.go @@ -1,7 +1,6 @@ package ci_test import ( - "fmt" "testing" "time" @@ -27,10 +26,8 @@ func TestCi(t *testing.T) { w, err := repository.Worktree() assert.NoError(t, err, "should get worktree") - w.Add(file.Name()) - - status, err := w.Status() - fmt.Println(status) + _, err = w.Add(file.Name()) + assert.NoError(t, err, "should add file") gitUtilInMemory := &gitutil.GitUtil{ Repository: repository, @@ -43,6 +40,7 @@ func TestCi(t *testing.T) { When: time.Now(), }, }) + assert.NoError(t, err, "should commit") testConfigs := []struct { service string From 7b4db67cb76e7900a15157ecfd1ba8e79319dfd7 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Sun, 21 Jul 2019 21:53:33 +0200 Subject: [PATCH 70/77] fix(internal/gitutil): allow lightweight tags --- internal/gitutil/gitutil.go | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/internal/gitutil/gitutil.go b/internal/gitutil/gitutil.go index 9372e4e..2588e5c 100644 --- a/internal/gitutil/gitutil.go +++ b/internal/gitutil/gitutil.go @@ -93,15 +93,10 @@ func (g *GitUtil) GetLastVersion() (*semver.Version, string, error) { err = gitTags.ForEach(func(p *plumbing.Reference) error { v, err := semver.NewVersion(p.Name().Short()) - log.Tracef("%+v", p.Name().Short()) + log.Tracef("%+v with hash: %s", p.Target(), p.Hash()) + if err == nil { - _, err := g.Repository.TagObject(p.Hash()) - if err == nil { - log.Debugf("Add tag %s", p.Name().Short()) - tags = append(tags, v) - } else { - log.Debugf("Found tag, but is not annotated, skip") - } + tags = append(tags, v) } else { log.Debugf("Tag %s is not a valid version, skip", p.Name().Short()) } @@ -126,13 +121,8 @@ func (g *GitUtil) GetLastVersion() (*semver.Version, string, error) { return nil, "", err } - tagObject, err := g.Repository.TagObject(tag.Hash()) - if err != nil { - return nil, "", err - } - - log.Debugf("Found old hash %s", tagObject.Target.String()) - return tags[0], tagObject.Target.String(), nil + log.Debugf("Found old hash %s", tag.Hash().String()) + return tags[0], tag.Hash().String(), nil } // GetCommits from git hash to HEAD @@ -155,9 +145,10 @@ func (g *GitUtil) GetCommits(lastTagHash string) ([]Commit, error) { if c.Hash.String() == lastTagHash { log.Debugf("Found commit with hash %s, will stop here", c.Hash.String()) foundEnd = true + } - log.Tracef("Found commit with hash %s", c.Hash.String()) if !foundEnd { + log.Tracef("Found commit with hash %s", c.Hash.String()) commit := Commit{ Message: c.Message, Author: c.Committer.Name, From 7d68d5835fef3d2aa0f45a4daaefcc9442c50a08 Mon Sep 17 00:00:00 2001 From: fwiedmann Date: Mon, 22 Jul 2019 00:48:13 +0200 Subject: [PATCH 71/77] test(internal/releaser/util): add test for CreateBearerHTTPClient and GetAccessToken --- internal/releaser/util/util.go | 2 ++ internal/releaser/util/util_test.go | 43 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 internal/releaser/util/util_test.go diff --git a/internal/releaser/util/util.go b/internal/releaser/util/util.go index 7c1f548..dac0acc 100644 --- a/internal/releaser/util/util.go +++ b/internal/releaser/util/util.go @@ -35,6 +35,8 @@ func GetAccessToken(providerName string) (string, error) { if token, exists = os.LookupEnv(envName); !exists { return "", fmt.Errorf("could not find %s in the enviroment variables. Please check if it is set", envName) + } else if token == "" { + return "", fmt.Errorf("token %s is set in environment variables but is empty", envName) } return token, nil } diff --git a/internal/releaser/util/util_test.go b/internal/releaser/util/util_test.go new file mode 100644 index 0000000..287f81f --- /dev/null +++ b/internal/releaser/util/util_test.go @@ -0,0 +1,43 @@ +package util_test + +import ( + "context" + "fmt" + "os" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/Nightapes/go-semantic-release/internal/releaser/util" +) + +func TestCreateBearerHTTPClient(t *testing.T) { + client := util.CreateBearerHTTPClient(context.Background(), "") + + assert.True(t, client != nil, "Client is empty") +} + +type testDoubleToken struct { + providerName, token string + valid bool +} + +var testDoubles = []testDoubleToken{ + testDoubleToken{providerName: "test0", token: "foo", valid: true}, + testDoubleToken{providerName: "test1", token: "", valid: false}, +} + +func TestGetAccessToken(t *testing.T) { + for _, testObject := range testDoubles { + envName := fmt.Sprintf("%s_ACCESS_TOKEN", strings.ToUpper(testObject.providerName)) + if err := os.Setenv(envName, testObject.token); err != nil { + fmt.Println(err.Error()) + } + + _, err := util.GetAccessToken(testObject.providerName) + + assert.Equal(t, testObject.valid, err == nil) + os.Unsetenv(envName) + } +} From 581b62d3249b0c48e194b28cd6f17d64ee4f7ee0 Mon Sep 17 00:00:00 2001 From: fwiedmann Date: Mon, 22 Jul 2019 18:11:48 +0200 Subject: [PATCH 72/77] ref(internal/releaser/util): check if asset name ist not empty, open file which should be zipped before create zip file --- internal/releaser/util/util.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/internal/releaser/util/util.go b/internal/releaser/util/util.go index dac0acc..6fc9882 100644 --- a/internal/releaser/util/util.go +++ b/internal/releaser/util/util.go @@ -45,7 +45,9 @@ func GetAccessToken(providerName string) (string, error) { func PrepareAssets(repository string, assets []config.Asset) ([]*string, error) { filesToUpload := []*string{} for _, asset := range assets { - if asset.Compress { + if asset.Name == "" { + return nil, fmt.Errorf("Asset name declaration is empty, please check your configuration file") + } else if asset.Compress { log.Debugf("Asset %s will now be compressed", asset.Name) log.Debugf("Repo url %s", repository) zipNameWithPath, err := zipFile(repository, asset.Name) @@ -65,6 +67,12 @@ func PrepareAssets(repository string, assets []config.Asset) ([]*string, error) // ZipFile compress given file in zip format func zipFile(repository string, file string) (string, error) { + fileToZip, err := os.Open(repository + "/" + file) + if err != nil { + return "", err + } + defer fileToZip.Close() + zipFileName := fmt.Sprintf("%s/%s.zip", strings.TrimSuffix(repository, "/"), file) zipFile, err := os.Create(zipFileName) @@ -75,12 +83,6 @@ func zipFile(repository string, file string) (string, error) { defer zipFile.Close() - fileToZip, err := os.Open(repository + "/" + file) - if err != nil { - return "", err - } - defer fileToZip.Close() - fileToZipInfo, err := fileToZip.Stat() if err != nil { return "", err From 5986e2819a3e09295e7727a741fa372090ae52e0 Mon Sep 17 00:00:00 2001 From: fwiedmann Date: Mon, 22 Jul 2019 18:13:11 +0200 Subject: [PATCH 73/77] test(internal/releaser/util): add test for PrepareAssets --- go.mod | 1 + internal/releaser/util/util_test.go | 76 +++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/go.mod b/go.mod index 6d9f669..d1e9cef 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.12 require ( github.com/Masterminds/semver v1.4.2 + github.com/coreos/etcd v3.3.10+incompatible github.com/gliderlabs/ssh v0.2.2 // indirect github.com/google/go-cmp v0.3.0 // indirect github.com/google/go-github/v25 v25.1.3 diff --git a/internal/releaser/util/util_test.go b/internal/releaser/util/util_test.go index 287f81f..9cf12b4 100644 --- a/internal/releaser/util/util_test.go +++ b/internal/releaser/util/util_test.go @@ -7,6 +7,8 @@ import ( "strings" "testing" + "github.com/Nightapes/go-semantic-release/pkg/config" + "github.com/stretchr/testify/assert" "github.com/Nightapes/go-semantic-release/internal/releaser/util" @@ -41,3 +43,77 @@ func TestGetAccessToken(t *testing.T) { os.Unsetenv(envName) } } + +type testDoubleFiles struct { + testFiles []config.Asset + valid bool +} + +var files = []testDoubleFiles{ + testDoubleFiles{ + testFiles: []config.Asset{ + config.Asset{ + Name: "file0", + Compress: true, + }, + config.Asset{ + Name: "file1", + Compress: true, + }, + }, + valid: true, + }, + testDoubleFiles{ + testFiles: []config.Asset{ + config.Asset{ + Name: "", + Compress: true, + }, + config.Asset{ + Name: "", + Compress: false, + }, + }, + valid: false, + }, +} + +func TestPrepareAssets(t *testing.T) { + for _, testObject := range files { + workDir, _ := os.Getwd() + filesToDelete := []string{} + + for _, testFile := range testObject.testFiles { + + if testFile.Name != "" { + filesToDelete = append(filesToDelete, testFile.Name) + + file, err := os.Create(testFile.Name) + if err != nil { + fmt.Print(err.Error()) + } + defer file.Close() + if testFile.Compress { + filesToDelete = append(filesToDelete, testFile.Name+".zip") + } + } + + } + preparedFiles, err := util.PrepareAssets(workDir, testObject.testFiles) + + if err == nil { + assert.Equal(t, 2, len(preparedFiles)) + } + + assert.Equal(t, testObject.valid, err == nil) + + for _, file := range filesToDelete { + if err := os.Remove(file); err != nil { + fmt.Println(err.Error()) + } + + } + + } + +} From 6267e1cc81784b3e753e8107a8d03d55dbb9618c Mon Sep 17 00:00:00 2001 From: Nightapes Date: Mon, 22 Jul 2019 20:46:48 +0200 Subject: [PATCH 74/77] refactor(pkg/semanticrelease): clean up code --- internal/cache/cache.go | 56 +++++++++++++--- internal/calculator/calculator.go | 68 +++++++++++++++++++ internal/releaser/util/util.go | 2 +- pkg/semanticrelease/helper.go | 87 ------------------------- pkg/semanticrelease/semantic-release.go | 38 ++++------- 5 files changed, 129 insertions(+), 122 deletions(-) create mode 100644 internal/calculator/calculator.go delete mode 100644 pkg/semanticrelease/helper.go diff --git a/internal/cache/cache.go b/internal/cache/cache.go index f3db59e..d459028 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -2,9 +2,12 @@ package cache import ( + log "github.com/sirupsen/logrus" "io/ioutil" "path" + "github.com/Masterminds/semver" + "github.com/Nightapes/go-semantic-release/internal/shared" "gopkg.in/yaml.v2" ) @@ -23,31 +26,68 @@ type ReleaseVersionEntry struct { } // Write version into .version -func Write(repository string, versionFileContent ReleaseVersion) error { +func Write(repository string, releaseVersion shared.ReleaseVersion) error { completePath := path.Join(path.Dir(repository), ".version") - data, err := yaml.Marshal(&versionFileContent) + toCache := &ReleaseVersion{ + Next: ReleaseVersionEntry{ + Commit: releaseVersion.Next.Commit, + Version: releaseVersion.Next.Version.String(), + }, + Last: ReleaseVersionEntry{ + Commit: releaseVersion.Last.Commit, + Version: releaseVersion.Last.Version.String(), + }, + Branch: releaseVersion.Branch, + Draft: releaseVersion.Draft, + } + + data, err := yaml.Marshal(toCache) if err != nil { return err } + log.Debugf("Save %s with hash %s to cache", releaseVersion.Next.Version.String(), releaseVersion.Next.Commit) return ioutil.WriteFile(completePath, data, 0644) } // Read version into .version -func Read(repository string) (*ReleaseVersion, error) { +func Read(repository string) (*shared.ReleaseVersion, error) { completePath := path.Join(path.Dir(repository), ".version") content, err := ioutil.ReadFile(completePath) if err != nil { - return &ReleaseVersion{}, err + return &shared.ReleaseVersion{}, err } - var versionFileContent ReleaseVersion - err = yaml.Unmarshal(content, &versionFileContent) + var parsedContent ReleaseVersion + err = yaml.Unmarshal(content, &parsedContent) if err != nil { - return &ReleaseVersion{}, err + return &shared.ReleaseVersion{}, err } - return &versionFileContent, nil + nextVersion, err := semver.NewVersion(parsedContent.Next.Version) + if err != nil { + return nil, err + } + + lastVersion, err := semver.NewVersion(parsedContent.Last.Version) + if err != nil { + return nil, err + } + + releaseVersion := &shared.ReleaseVersion{ + Next: shared.ReleaseVersionEntry{ + Commit: parsedContent.Next.Commit, + Version: nextVersion, + }, + Last: shared.ReleaseVersionEntry{ + Commit: parsedContent.Last.Commit, + Version: lastVersion, + }, + Branch: parsedContent.Branch, + Draft: parsedContent.Draft, + } + log.Infof("Found cache, will return cached version %s", parsedContent.Next.Version) + return releaseVersion, nil } diff --git a/internal/calculator/calculator.go b/internal/calculator/calculator.go new file mode 100644 index 0000000..d2541fb --- /dev/null +++ b/internal/calculator/calculator.go @@ -0,0 +1,68 @@ +package calculator + +import ( + "strconv" + "strings" + + "github.com/Masterminds/semver" + "github.com/Nightapes/go-semantic-release/internal/analyzer" + + log "github.com/sirupsen/logrus" +) + +// Calculator struct +type Calculator struct{} + +// New Calculator struct +func New() *Calculator { + return &Calculator{} +} + +//IncPrerelease increase prerelease by one +func (c *Calculator) IncPrerelease(preReleaseType string, version *semver.Version) (semver.Version, error) { + defaultPrerelease := preReleaseType + ".0" + if version.Prerelease() == "" || !strings.HasPrefix(version.Prerelease(), preReleaseType) { + return version.SetPrerelease(defaultPrerelease) + } + + parts := strings.Split(version.Prerelease(), ".") + if len(parts) == 2 { + i, err := strconv.Atoi(parts[1]) + if err != nil { + log.Warnf("Could not parse release tag %s, use version %s", version.Prerelease(), version.String()) + return version.SetPrerelease(defaultPrerelease) + } + return version.SetPrerelease(preReleaseType + "." + strconv.Itoa((i + 1))) + + } + log.Warnf("Could not parse release tag %s, use version %s", version.Prerelease(), version.String()) + return version.SetPrerelease(defaultPrerelease) +} + +//CalculateNewVersion from given commits and lastversion +func (c *Calculator) CalculateNewVersion(commits map[analyzer.Release][]analyzer.AnalyzedCommit, lastVersion *semver.Version, releaseType string, firstRelease bool) (semver.Version, bool) { + switch releaseType { + case "beta", "alpha": + if len(commits["major"]) > 0 || len(commits["minor"]) > 0 || len(commits["patch"]) > 0 { + version, _ := c.IncPrerelease(releaseType, lastVersion) + return version, true + } + case "rc": + if len(commits["major"]) > 0 || len(commits["minor"]) > 0 || len(commits["patch"]) > 0 { + version, _ := c.IncPrerelease(releaseType, lastVersion) + return version, false + } + case "release": + if !firstRelease { + if len(commits["major"]) > 0 { + return lastVersion.IncMajor(), false + } else if len(commits["minor"]) > 0 { + return lastVersion.IncMinor(), false + } else if len(commits["patch"]) > 0 { + return lastVersion.IncPatch(), false + } + } + } + + return *lastVersion, false +} diff --git a/internal/releaser/util/util.go b/internal/releaser/util/util.go index 6fc9882..86745e1 100644 --- a/internal/releaser/util/util.go +++ b/internal/releaser/util/util.go @@ -46,7 +46,7 @@ func PrepareAssets(repository string, assets []config.Asset) ([]*string, error) filesToUpload := []*string{} for _, asset := range assets { if asset.Name == "" { - return nil, fmt.Errorf("Asset name declaration is empty, please check your configuration file") + return nil, fmt.Errorf("asset name declaration is empty, please check your configuration file") } else if asset.Compress { log.Debugf("Asset %s will now be compressed", asset.Name) log.Debugf("Repo url %s", repository) diff --git a/pkg/semanticrelease/helper.go b/pkg/semanticrelease/helper.go deleted file mode 100644 index 990f57e..0000000 --- a/pkg/semanticrelease/helper.go +++ /dev/null @@ -1,87 +0,0 @@ -package semanticrelease - -import ( - "strconv" - "strings" - - "github.com/Masterminds/semver" - "github.com/Nightapes/go-semantic-release/internal/cache" - "github.com/Nightapes/go-semantic-release/internal/shared" - log "github.com/sirupsen/logrus" -) - -func (s *SemanticRelease) 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 -} - -func (s *SemanticRelease) saveToCache(releaseVersion shared.ReleaseVersion) error { - - toCache := cache.ReleaseVersion{ - Next: cache.ReleaseVersionEntry{ - Commit: releaseVersion.Next.Commit, - Version: releaseVersion.Next.Version.String(), - }, - Last: cache.ReleaseVersionEntry{ - Commit: releaseVersion.Last.Commit, - Version: releaseVersion.Last.Version.String(), - }, - Branch: releaseVersion.Branch, - } - - log.Debugf("Save %s with hash %s to cache", releaseVersion.Next.Version.String(), releaseVersion.Next.Commit) - return cache.Write(s.repository, toCache) -} - -func (s *SemanticRelease) readFromCache(currentHash string) (*shared.ReleaseVersion, error) { - content, err := cache.Read(s.repository) - - if err == nil && content.Next.Commit == currentHash { - - nextVersion, err := semver.NewVersion(content.Next.Version) - if err != nil { - return nil, err - } - - lastVersion, err := semver.NewVersion(content.Last.Version) - if err != nil { - return nil, err - } - - releaseVersion := &shared.ReleaseVersion{ - Next: shared.ReleaseVersionEntry{ - Commit: content.Next.Commit, - Version: nextVersion, - }, - Last: shared.ReleaseVersionEntry{ - Commit: content.Last.Commit, - Version: lastVersion, - }, - Branch: content.Branch, - } - - log.Infof("Found cache, will return cached version %s", content.Next.Version) - return releaseVersion, nil - - } - log.Debugf("Mismatch git and version file %s - %s", content.Next.Commit, currentHash) - return nil, nil -} diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index 979ba2b..bbdade5 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -8,6 +8,8 @@ import ( "github.com/Masterminds/semver" "github.com/Nightapes/go-semantic-release/internal/analyzer" + "github.com/Nightapes/go-semantic-release/internal/cache" + "github.com/Nightapes/go-semantic-release/internal/calculator" "github.com/Nightapes/go-semantic-release/internal/changelog" "github.com/Nightapes/go-semantic-release/internal/ci" "github.com/Nightapes/go-semantic-release/internal/gitutil" @@ -23,6 +25,7 @@ type SemanticRelease struct { config *config.ReleaseConfig gitutil *gitutil.GitUtil analyzer *analyzer.Analyzer + calculator *calculator.Calculator releaser releaser.Releaser repository string } @@ -50,6 +53,7 @@ func New(c *config.ReleaseConfig, repository string) (*SemanticRelease, error) { releaser: releaser, analyzer: analyzer, repository: repository, + calculator: calculator.New(), }, nil } @@ -70,12 +74,12 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er log.Debugf("Ignore .version file if exits, %t", force) if !force { - releaseVersion, err := s.readFromCache(provider.Commit) + releaseVersion, err := cache.Read(s.repository) if err != nil { return nil, err } - if releaseVersion != nil { + if releaseVersion.Next.Commit == provider.Commit && releaseVersion != nil { return releaseVersion, nil } } @@ -85,16 +89,12 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er return nil, err } - var newVersion semver.Version firstRelease := false if lastVersion == nil { defaultVersion, _ := semver.NewVersion("1.0.0") - newVersion = *defaultVersion lastVersion = defaultVersion firstRelease = true - } else { - newVersion = *lastVersion } commits, err := s.gitutil.GetCommits(lastVersionHash) @@ -108,28 +108,14 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er if err != nil { return nil, err } - result := a.Analyze(commits) + isDraft := false + var newVersion semver.Version for branch, releaseType := range s.config.Branch { if provider.Branch == branch || strings.HasPrefix(provider.Branch, branch) { log.Debugf("Found branch config for branch %s with release type %s", provider.Branch, releaseType) - switch releaseType { - case "beta", "alpha": - isDraft = true - newVersion = s.incPrerelease(releaseType, newVersion) - case "rc": - newVersion = s.incPrerelease(releaseType, newVersion) - case "release": - if !firstRelease { - if len(result["major"]) > 0 { - newVersion = newVersion.IncMajor() - } else if len(result["minor"]) > 0 { - newVersion = newVersion.IncMinor() - } else if len(result["patch"]) > 0 { - newVersion = newVersion.IncPatch() - } - } - } + newVersion, isDraft = s.calculator.CalculateNewVersion(a.Analyze(commits), lastVersion, releaseType, firstRelease) + break } } @@ -147,7 +133,7 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er } log.Infof("New version %s -> %s", lastVersion.String(), newVersion.String()) - err = s.saveToCache(releaseVersion) + err = cache.Write(s.repository, releaseVersion) if err != nil { return nil, err } @@ -176,7 +162,7 @@ func (s *SemanticRelease) SetVersion(version string) error { lastVersion, _ = semver.NewVersion("1.0.0") } - return s.saveToCache(shared.ReleaseVersion{ + return cache.Write(s.repository, shared.ReleaseVersion{ Next: shared.ReleaseVersionEntry{ Commit: provider.Commit, Version: newVersion, From e222734a1ac8ee78eab5d7ab65024f73d70837e4 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Mon, 22 Jul 2019 20:47:10 +0200 Subject: [PATCH 75/77] test(internal/*): add more unit tests --- internal/cache/cache_test.go | 32 +++- internal/calculator/calculator_test.go | 219 +++++++++++++++++++++++++ 2 files changed, 244 insertions(+), 7 deletions(-) create mode 100644 internal/calculator/calculator_test.go diff --git a/internal/cache/cache_test.go b/internal/cache/cache_test.go index 3ca28b0..07d619e 100644 --- a/internal/cache/cache_test.go +++ b/internal/cache/cache_test.go @@ -3,7 +3,9 @@ package cache_test import ( "testing" + "github.com/Masterminds/semver" "github.com/Nightapes/go-semantic-release/internal/cache" + "github.com/Nightapes/go-semantic-release/internal/shared" "github.com/stretchr/testify/assert" "io/ioutil" "os" @@ -39,14 +41,14 @@ func TestWriteAndReadCache(t *testing.T) { assert.NoError(t, err) - content := cache.ReleaseVersion{ - Last: cache.ReleaseVersionEntry{ + content := shared.ReleaseVersion{ + Last: shared.ReleaseVersionEntry{ Commit: "12345", - Version: "1.0.0", + Version: createVersion("1.0.0"), }, - Next: cache.ReleaseVersionEntry{ + Next: shared.ReleaseVersionEntry{ Commit: "12346", - Version: "1.1.0", + Version: createVersion("1.1.0"), }, Branch: "master", Draft: true, @@ -59,13 +61,29 @@ func TestWriteAndReadCache(t *testing.T) { result, readError := cache.Read(dir) assert.NoErrorf(t, readError, "Should read file") - assert.Equal(t, &content, result) + assert.EqualValues(t, &content, result) } func TestWriteNotFound(t *testing.T) { - err := cache.Write("notfound/dir", cache.ReleaseVersion{}) + 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", + Draft: true, + }) assert.Errorf(t, err, "Write non exsiting file") } + +func createVersion(version string) *semver.Version { + ver, _ := semver.NewVersion(version) + return ver +} diff --git a/internal/calculator/calculator_test.go b/internal/calculator/calculator_test.go new file mode 100644 index 0000000..5c8f2b4 --- /dev/null +++ b/internal/calculator/calculator_test.go @@ -0,0 +1,219 @@ +package calculator_test + +import ( + "testing" + + "github.com/Masterminds/semver" + "github.com/Nightapes/go-semantic-release/internal/analyzer" + "github.com/Nightapes/go-semantic-release/internal/calculator" + "github.com/stretchr/testify/assert" +) + +func createVersion(version string) *semver.Version { + ver, _ := semver.NewVersion(version) + return ver +} + +func TestCalculator_IncPrerelease(t *testing.T) { + + testConfigs := []struct { + testCase string + preReleaseType string + lastVersion *semver.Version + nextVersion string + hasError bool + }{ + { + testCase: "version without preRelease", + preReleaseType: "alpha", + lastVersion: createVersion("1.0.0"), + nextVersion: "1.0.0-alpha.0", + }, + { + testCase: "version with preRelease", + preReleaseType: "alpha", + lastVersion: createVersion("1.0.0-alpha.0"), + nextVersion: "1.0.0-alpha.1", + }, + { + testCase: "version with preRelease, change type", + preReleaseType: "beta", + lastVersion: createVersion("1.0.0-alpha.0"), + nextVersion: "1.0.0-beta.0", + }, + { + testCase: "version with preRelease but broken", + preReleaseType: "alpha", + lastVersion: createVersion("1.0.0-alpha.br0ken"), + nextVersion: "1.0.0-alpha.0", + }, + { + testCase: "version with preRelease but broken 2", + preReleaseType: "alpha", + lastVersion: createVersion("1.0.0-alphabr0ken"), + nextVersion: "1.0.0-alpha.0", + }, + } + + c := calculator.New() + + for _, test := range testConfigs { + next, err := c.IncPrerelease(test.preReleaseType, test.lastVersion) + assert.Equalf(t, test.hasError, err != nil, "Testcase %s should have error: %t -> %s", test.testCase, test.hasError, err) + assert.Equal(t, test.nextVersion, next.String()) + } + +} + +func TestCalculator_CalculateNewVersion(t *testing.T) { + + testConfigs := []struct { + testCase string + releaseType string + lastVersion *semver.Version + nextVersion string + isDraft bool + isFirst bool + analyzedCommits map[analyzer.Release][]analyzer.AnalyzedCommit + }{ + { + testCase: "version with preRelease alpha", + releaseType: "alpha", + lastVersion: createVersion("1.0.0"), + nextVersion: "1.0.0-alpha.0", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "major": []analyzer.AnalyzedCommit{}, + "minor": []analyzer.AnalyzedCommit{ + analyzer.AnalyzedCommit{}, + }, + "patch": []analyzer.AnalyzedCommit{}, + "none": []analyzer.AnalyzedCommit{}, + }, + isFirst: false, + isDraft: true, + }, + { + testCase: "version with preRelease beta", + releaseType: "beta", + lastVersion: createVersion("1.0.0"), + nextVersion: "1.0.0-beta.0", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "major": []analyzer.AnalyzedCommit{}, + "minor": []analyzer.AnalyzedCommit{ + analyzer.AnalyzedCommit{}, + }, + "patch": []analyzer.AnalyzedCommit{}, + "none": []analyzer.AnalyzedCommit{}, + }, + isFirst: false, + isDraft: true, + }, + { + testCase: "version without commits", + releaseType: "alpha", + lastVersion: createVersion("1.0.0"), + nextVersion: "1.0.0", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "major": []analyzer.AnalyzedCommit{}, + "minor": []analyzer.AnalyzedCommit{}, + "patch": []analyzer.AnalyzedCommit{}, + "none": []analyzer.AnalyzedCommit{}, + }, + isFirst: false, + isDraft: false, + }, + { + testCase: "version with commits and first release", + releaseType: "release", + lastVersion: createVersion("1.0.0"), + nextVersion: "1.0.0", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "major": []analyzer.AnalyzedCommit{analyzer.AnalyzedCommit{}}, + "minor": []analyzer.AnalyzedCommit{}, + "patch": []analyzer.AnalyzedCommit{}, + "none": []analyzer.AnalyzedCommit{}, + }, + isFirst: true, + isDraft: false, + }, + { + testCase: "version with commits and rc release", + releaseType: "rc", + lastVersion: createVersion("1.0.0"), + nextVersion: "1.0.0-rc.0", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "major": []analyzer.AnalyzedCommit{analyzer.AnalyzedCommit{}}, + "minor": []analyzer.AnalyzedCommit{analyzer.AnalyzedCommit{}}, + "patch": []analyzer.AnalyzedCommit{analyzer.AnalyzedCommit{}}, + "none": []analyzer.AnalyzedCommit{}, + }, + isFirst: false, + isDraft: false, + }, + { + testCase: "version with commits and rc release", + releaseType: "rc", + lastVersion: createVersion("1.0.0-rc.0"), + nextVersion: "1.0.0-rc.1", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "major": []analyzer.AnalyzedCommit{}, + "minor": []analyzer.AnalyzedCommit{analyzer.AnalyzedCommit{}}, + "patch": []analyzer.AnalyzedCommit{analyzer.AnalyzedCommit{}}, + "none": []analyzer.AnalyzedCommit{}, + }, + isFirst: false, + isDraft: false, + }, + { + testCase: "version with commits and major release", + releaseType: "release", + lastVersion: createVersion("1.0.0"), + nextVersion: "2.0.0", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "major": []analyzer.AnalyzedCommit{analyzer.AnalyzedCommit{}}, + "minor": []analyzer.AnalyzedCommit{analyzer.AnalyzedCommit{}}, + "patch": []analyzer.AnalyzedCommit{analyzer.AnalyzedCommit{}}, + "none": []analyzer.AnalyzedCommit{}, + }, + isFirst: false, + isDraft: false, + }, + { + testCase: "version with commits and minor release", + releaseType: "release", + lastVersion: createVersion("1.0.0"), + nextVersion: "1.1.0", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "major": []analyzer.AnalyzedCommit{}, + "minor": []analyzer.AnalyzedCommit{analyzer.AnalyzedCommit{}}, + "patch": []analyzer.AnalyzedCommit{analyzer.AnalyzedCommit{}}, + "none": []analyzer.AnalyzedCommit{}, + }, + isFirst: false, + isDraft: false, + }, + { + testCase: "version with commits and minor patch", + releaseType: "release", + lastVersion: createVersion("1.0.0"), + nextVersion: "1.0.1", + analyzedCommits: map[analyzer.Release][]analyzer.AnalyzedCommit{ + "major": []analyzer.AnalyzedCommit{}, + "minor": []analyzer.AnalyzedCommit{}, + "patch": []analyzer.AnalyzedCommit{analyzer.AnalyzedCommit{}}, + "none": []analyzer.AnalyzedCommit{}, + }, + isFirst: false, + isDraft: false, + }, + } + + c := calculator.New() + + for _, test := range testConfigs { + next, draft := c.CalculateNewVersion(test.analyzedCommits, test.lastVersion, test.releaseType, test.isFirst) + assert.Equalf(t, test.isDraft, draft, "Should have draft %t for testcase %s", test.isDraft, test.testCase) + assert.Equalf(t, test.nextVersion, next.String(), "Should have version %s for testcase %s", test.nextVersion, test.testCase) + } + +} From 1daff2bc8aa4f245178b1db130c489bb39fa5eb2 Mon Sep 17 00:00:00 2001 From: Nightapes Date: Wed, 24 Jul 2019 22:14:03 +0200 Subject: [PATCH 76/77] refactor(pkg): clean up semantic release interface --- cmd/go-semantic-release/commands/changelog.go | 10 +- cmd/go-semantic-release/commands/next.go | 12 +- cmd/go-semantic-release/commands/release.go | 8 +- cmd/go-semantic-release/commands/set.go | 7 +- internal/cache/cache.go | 2 +- internal/ci/ci.go | 2 +- pkg/config/config.go | 2 +- pkg/config/config_test.go | 112 ++++++++++++++++++ pkg/semanticrelease/semantic-release.go | 79 ++++-------- 9 files changed, 171 insertions(+), 63 deletions(-) create mode 100644 pkg/config/config_test.go diff --git a/cmd/go-semantic-release/commands/changelog.go b/cmd/go-semantic-release/commands/changelog.go index 98968f1..625b020 100644 --- a/cmd/go-semantic-release/commands/changelog.go +++ b/cmd/go-semantic-release/commands/changelog.go @@ -40,12 +40,18 @@ var changelogCmd = &cobra.Command{ return err } - releaseVersion, err := s.GetNextVersion(force) + provider, err := s.GetCIProvider() if err != nil { return err } - generatedChangelog, err := s.GetChangelog(releaseVersion) + releaseVersion, commits, err := s.GetNextVersion(provider, force) + if err != nil { + return err + } + log.Debugf("Found %d commits till last release", len(commits)) + + generatedChangelog, err := s.GetChangelog(commits, releaseVersion) if err != nil { return err } diff --git a/cmd/go-semantic-release/commands/next.go b/cmd/go-semantic-release/commands/next.go index 0f64259..65ed0bc 100644 --- a/cmd/go-semantic-release/commands/next.go +++ b/cmd/go-semantic-release/commands/next.go @@ -2,8 +2,8 @@ package commands import ( "fmt" - "github.com/Nightapes/go-semantic-release/pkg/semanticrelease" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -35,7 +35,15 @@ var nextCmd = &cobra.Command{ return err } - releaseVersion, err := s.GetNextVersion(force) + provider, err := s.GetCIProvider() + + if err != nil { + log.Infof("Will not calculate version, set fake version. Could not find CI Provider, if running locally, set env CI=true") + fmt.Println("0.0.0-fake.0") + return nil + } + + releaseVersion, _, err := s.GetNextVersion(provider, force) if err != nil { return err } diff --git a/cmd/go-semantic-release/commands/release.go b/cmd/go-semantic-release/commands/release.go index 7d981ca..efdd0f8 100644 --- a/cmd/go-semantic-release/commands/release.go +++ b/cmd/go-semantic-release/commands/release.go @@ -32,6 +32,12 @@ var releaseCmd = &cobra.Command{ if err != nil { return err } - return s.Release(force) + + provider, err := s.GetCIProvider() + if err != nil { + return err + } + + return s.Release(provider, force) }, } diff --git a/cmd/go-semantic-release/commands/set.go b/cmd/go-semantic-release/commands/set.go index 2f580fe..e98618d 100644 --- a/cmd/go-semantic-release/commands/set.go +++ b/cmd/go-semantic-release/commands/set.go @@ -31,6 +31,11 @@ var setCmd = &cobra.Command{ return err } - return s.SetVersion(args[0]) + provider, err := s.GetCIProvider() + if err != nil { + return err + } + + return s.SetVersion(provider, args[0]) }, } diff --git a/internal/cache/cache.go b/internal/cache/cache.go index d459028..0c33d48 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -47,7 +47,7 @@ func Write(repository string, releaseVersion shared.ReleaseVersion) error { return err } - log.Debugf("Save %s with hash %s to cache", releaseVersion.Next.Version.String(), releaseVersion.Next.Commit) + log.Infof("Save %s with hash %s to cache", releaseVersion.Next.Version.String(), releaseVersion.Next.Commit) return ioutil.WriteFile(completePath, data, 0644) } diff --git a/internal/ci/ci.go b/internal/ci/ci.go index 124e9a9..4f1acd6 100644 --- a/internal/ci/ci.go +++ b/internal/ci/ci.go @@ -51,7 +51,7 @@ func GetCIProvider(gitUtil *gitutil.GitUtil, envs map[string]string) (*ProviderC log.Infof("Found CI: %s", config.Name) return config, nil } - log.Infof("%s", err.Error()) + log.Debugf("%s", err.Error()) } return nil, fmt.Errorf("could not find any CI, if running locally set env CI=true") } diff --git a/pkg/config/config.go b/pkg/config/config.go index 62a2a4d..7c08d77 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -55,7 +55,7 @@ func Read(configPath string) (*ReleaseConfig, error) { return &ReleaseConfig{}, err } - log.Debugf("Found config %+v", releaseConfig) + log.Tracef("Found config %+v", releaseConfig) return &releaseConfig, nil } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go new file mode 100644 index 0000000..ca3cc13 --- /dev/null +++ b/pkg/config/config_test.go @@ -0,0 +1,112 @@ +package config_test + +import ( + "testing" + + "github.com/Nightapes/go-semantic-release/pkg/config" + "github.com/stretchr/testify/assert" + "io/ioutil" + "os" + "path" +) + +func TestReadCacheNotFound(t *testing.T) { + + _, err := config.Read("notfound/dir") + assert.Errorf(t, err, "Read non exsiting file") + +} + +func TestReadCacheInvalidContent(t *testing.T) { + + dir, err := ioutil.TempDir("", "prefix") + assert.NoError(t, err) + defer os.RemoveAll(dir) + + completePath := path.Join(path.Dir(dir), ".release.yml") + brokenContent := []byte("hello broken\ngo: lang\n") + err = ioutil.WriteFile(completePath, brokenContent, 0644) + assert.NoError(t, err) + + _, readError := config.Read(completePath) + assert.Errorf(t, readError, "Should give error, when broken content") + +} + +func TestWriteAndReadCache(t *testing.T) { + + dir, err := ioutil.TempDir("", "prefix") + + assert.NoError(t, err) + defer os.RemoveAll(dir) + + completePath := path.Join(path.Dir(dir), ".release.yml") + content := []byte(` +commitFormat: angular +title: "go-semantic-release release" +branch: + master: release + rc: rc + beta: beta + alpha: alpha + add_git_releases: alpha +changelog: + printAll: false + template: '' + templatePath: '' +release: 'github' +assets: + - name: ./build/go-semantic-release + compress: false +github: + repo: "go-semantic-release" + user: "nightapes" + customUrl: "" +`) + err = ioutil.WriteFile(completePath, content, 0644) + assert.NoError(t, err) + + result, readError := config.Read(completePath) + assert.NoErrorf(t, readError, "Should read file") + + assert.EqualValues(t, &config.ReleaseConfig{ + CommitFormat: "angular", + Branch: map[string]string{"add_git_releases": "alpha", "alpha": "alpha", "beta": "beta", "master": "release", "rc": "rc"}, + Changelog: config.ChangelogConfig{ + PrintAll: false, + Template: "", + TemplatePath: ""}, + Release: "github", + GitHubProvider: config.GitHubProvider{ + Repo: "go-semantic-release", + User: "nightapes", + CustomURL: "", + AccessToken: ""}, + Assets: []config.Asset{ + config.Asset{ + Name: "./build/go-semantic-release", + Compress: false}}, + ReleaseTitle: "go-semantic-release release", + IsPreRelease: false, + IsDraft: false, + }, 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", +// Draft: true, +// }) +// assert.Errorf(t, err, "Write non exsiting file") + +// } diff --git a/pkg/semanticrelease/semantic-release.go b/pkg/semanticrelease/semantic-release.go index bbdade5..4d90658 100644 --- a/pkg/semanticrelease/semantic-release.go +++ b/pkg/semanticrelease/semantic-release.go @@ -1,7 +1,6 @@ package semanticrelease import ( - "fmt" "io/ioutil" "strings" "time" @@ -57,36 +56,28 @@ func New(c *config.ReleaseConfig, repository string) (*SemanticRelease, error) { }, nil } +//GetCIProvider result with ci config +func (s *SemanticRelease) GetCIProvider() (*ci.ProviderConfig, error) { + return ci.GetCIProvider(s.gitutil, ci.ReadAllEnvs()) +} + // GetNextVersion from .version or calculate new from commits -func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, error) { - provider, err := ci.GetCIProvider(s.gitutil, ci.ReadAllEnvs()) - - if err != nil { - fakeVersion, _ := semver.NewVersion("0.0.0-fake.0") - log.Warnf("Will not calculate version, set fake version. Could not find CI Provider, if running locally, set env CI=true") - return &shared.ReleaseVersion{ - Next: shared.ReleaseVersionEntry{ - Commit: "", - Version: fakeVersion, - }, - }, nil - } - +func (s *SemanticRelease) GetNextVersion(provider *ci.ProviderConfig, force bool) (*shared.ReleaseVersion, map[analyzer.Release][]analyzer.AnalyzedCommit, error) { log.Debugf("Ignore .version file if exits, %t", force) if !force { releaseVersion, err := cache.Read(s.repository) if err != nil { - return nil, err + return nil, nil, err } if releaseVersion.Next.Commit == provider.Commit && releaseVersion != nil { - return releaseVersion, nil + return releaseVersion, nil, nil } } lastVersion, lastVersionHash, err := s.gitutil.GetLastVersion() if err != nil { - return nil, err + return nil, nil, err } firstRelease := false @@ -99,22 +90,19 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er commits, err := s.gitutil.GetCommits(lastVersionHash) if err != nil { - return nil, err + return nil, nil, err } log.Debugf("Found %d commits till last release", len(commits)) - a, err := analyzer.New(s.config.CommitFormat, s.config.Changelog) - if err != nil { - return nil, err - } + analyzedCommits := s.analyzer.Analyze(commits) isDraft := false var newVersion semver.Version for branch, releaseType := range s.config.Branch { if provider.Branch == branch || strings.HasPrefix(provider.Branch, branch) { log.Debugf("Found branch config for branch %s with release type %s", provider.Branch, releaseType) - newVersion, isDraft = s.calculator.CalculateNewVersion(a.Analyze(commits), lastVersion, releaseType, firstRelease) + newVersion, isDraft = s.calculator.CalculateNewVersion(analyzedCommits, lastVersion, releaseType, firstRelease) break } } @@ -135,25 +123,19 @@ func (s *SemanticRelease) GetNextVersion(force bool) (*shared.ReleaseVersion, er log.Infof("New version %s -> %s", lastVersion.String(), newVersion.String()) err = cache.Write(s.repository, releaseVersion) if err != nil { - return nil, err + return nil, nil, err } - return &releaseVersion, err + return &releaseVersion, analyzedCommits, err } //SetVersion for git repository -func (s *SemanticRelease) SetVersion(version string) error { +func (s *SemanticRelease) SetVersion(provider *ci.ProviderConfig, version string) error { newVersion, err := semver.NewVersion(version) if err != nil { return err } - provider, err := ci.GetCIProvider(s.gitutil, ci.ReadAllEnvs()) - - if err != nil { - return fmt.Errorf("will not set version. Could not find CI Provider, if running locally, set env CI=true") - } - lastVersion, lastVersionHash, err := s.gitutil.GetLastVersion() if err != nil { return err @@ -176,23 +158,14 @@ func (s *SemanticRelease) SetVersion(version string) error { } // GetChangelog from last version till now -func (s *SemanticRelease) GetChangelog(releaseVersion *shared.ReleaseVersion) (*shared.GeneratedChangelog, error) { - commits, err := s.gitutil.GetCommits(releaseVersion.Last.Commit) - if err != nil { - return nil, err - } - - result := s.analyzer.Analyze(commits) - - log.Debugf("Found %d commits till last release", len(commits)) - +func (s *SemanticRelease) GetChangelog(analyzedCommits map[analyzer.Release][]analyzer.AnalyzedCommit, releaseVersion *shared.ReleaseVersion) (*shared.GeneratedChangelog, error) { c := changelog.New(s.config, s.analyzer.GetRules(), time.Now()) return c.GenerateChanglog(shared.ChangelogTemplateConfig{ Version: releaseVersion.Next.Version.String(), Hash: releaseVersion.Last.Commit, CommitURL: s.releaser.GetCommitURL(), CompareURL: s.releaser.GetCompareURL(releaseVersion.Last.Version.String(), releaseVersion.Next.Version.String()), - }, result) + }, analyzedCommits) } @@ -202,14 +175,7 @@ func (s *SemanticRelease) WriteChangeLog(changelogContent, file string) error { } // Release pusblish release to provider -func (s *SemanticRelease) Release(force bool) error { - - provider, err := ci.GetCIProvider(s.gitutil, ci.ReadAllEnvs()) - - if err != nil { - log.Debugf("Will not perform a new release. Could not find CI Provider") - return nil - } +func (s *SemanticRelease) Release(provider *ci.ProviderConfig, force bool) error { if provider.IsPR { log.Debugf("Will not perform a new release. This is a pull request") @@ -221,13 +187,18 @@ func (s *SemanticRelease) Release(force bool) error { return nil } - releaseVersion, err := s.GetNextVersion(force) + releaseVersion, analyzedCommits, err := s.GetNextVersion(provider, force) if err != nil { log.Debugf("Could not get next version") return err } - generatedChanglog, err := s.GetChangelog(releaseVersion) + if releaseVersion.Next.Version.Equal(releaseVersion.Next.Version) { + log.Infof("No new version, no release needed") + return nil + } + + generatedChanglog, err := s.GetChangelog(analyzedCommits, releaseVersion) if err != nil { log.Debugf("Could not get changelog") return err From 6bdbc2173f44886ccfe28ecb4a46a4a24080ba58 Mon Sep 17 00:00:00 2001 From: fwiedmann Date: Sun, 28 Jul 2019 21:53:30 +0200 Subject: [PATCH 77/77] chore(release.yaml): set master branch on beta release --- .release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.release.yml b/.release.yml index 4c380f9..f505632 100644 --- a/.release.yml +++ b/.release.yml @@ -1,7 +1,7 @@ commitFormat: angular title: "go-semantic-release release" branch: - master: release + master: beta rc: rc beta: beta alpha: alpha