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 }