Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add feature to allow specifying version upgrade type on arguments list. #17

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
v1.1.0
- Add `upgrade-type` argument option to allow manually specifying version type upgrade (@esequiel.virtuoso)

v1.0.5
- Fix isSetNewVersion function logic (@esequiel.virtuoso)

Expand Down
38 changes: 35 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,16 @@ stages:

semantic-release:
stage: semantic-release
variables:
SEMANTIC_RELEASE_VERSION: latest
dependencies: []
only:
refs:
- master
before_script:
- docker pull registry.com/dataplatform/semantic-release:latest
before_script:
- docker pull registry.com/dataplatform/semantic-release:$SEMANTIC_RELEASE_VERSION
script:
- docker run registry.com/dataplatform/semantic-release:latest up -git-host ${CI_SERVER_HOST} -git-group ${CI_PROJECT_NAMESPACE} -git-project ${CI_PROJECT_NAME} -username ${PPD2_USERNAME} -password ${PPD2_ACCESS_TOKEN}
- docker run registry.com/dataplatform/semantic-release:$SEMANTIC_RELEASE_VERSION up -git-host ${CI_SERVER_HOST} -git-group ${CI_PROJECT_NAMESPACE} -git-project ${CI_PROJECT_NAME} -username ${PPD2_USERNAME} -password ${PPD2_ACCESS_TOKEN}

```

Expand Down Expand Up @@ -77,6 +80,35 @@ setup(
)
```

### Upgrade specific type

Moreover, semantic release allows us to set a specific part of the version with the argument `upgrade-type` that can be set as `major`, `minor`, or `patch` as follows.

```yaml
stages:
- semantic-release

semantic-release:
stage: major-upgrade
when: manual
variables:
SEMANTIC_RELEASE_VERSION: latest
UPGRADE_TYPE: major
dependencies: []
only:
refs:
- master
before_script:
- docker pull registry.com/dataplatform/semantic-release:$SEMANTIC_RELEASE_VERSION
script:
- docker run registry.com/dataplatform/semantic-release:$SEMANTIC_RELEASE_VERSION up -upgrade-type $UPGRADE_TYPE -git-host ${CI_SERVER_HOST} -git-group ${CI_PROJECT_NAMESPACE} -git-project ${CI_PROJECT_NAME} -username ${PPD2_USERNAME} -password ${PPD2_ACCESS_TOKEN}

```

- If the current version is `1.2.3` and you set `upgrade-type` as `major` the new version will be `2.0.0`;
- If the current version is `1.2.3` and you set `upgrade-type` as `minor` the new version will be `1.3.0`;
- If the current version is `1.2.3` and you set `upgrade-type` as `patch` the new version will be `1.2.4`;

### If you need more information about the semantic release CLI usage you can run the following command.

```
Expand Down
7 changes: 4 additions & 3 deletions cmd/semantic-release/semantic-release.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func main() {
groupName := upgradeVersionCmd.String("git-group", "", "Git group name. (required)")
projectName := upgradeVersionCmd.String("git-project", "", "Git project name. (required)")
upgradePyFile := upgradeVersionCmd.Bool("setup-py", false, "Upgrade version in setup.py file. (default false)")
upgradeType := upgradeVersionCmd.String("upgrade-type", "", "Version to upgrade. I.e.: major, minor, patch.")
username := upgradeVersionCmd.String("username", "", "Git username. (required)")
password := upgradeVersionCmd.String("password", "", "Git password. (required)")
logLevel := upgradeVersionCmd.String("log-level", "debug", "Log level.")
Expand All @@ -67,7 +68,7 @@ func main() {
case "up":
logger.Info(colorYellow + "\nSemantic Version just started the process...\n\n" + colorReset)

semantic := newSemantic(logger, upgradeVersionCmd, gitHost, groupName, projectName, username, password, upgradePyFile)
semantic := newSemantic(logger, upgradeVersionCmd, gitHost, groupName, projectName, username, password, upgradePyFile, upgradeType)

if err := semantic.GenerateNewRelease(); err != nil {
logger.Error(err.Error())
Expand Down Expand Up @@ -180,7 +181,7 @@ func printCommitMessageExample() {
fmt.Println("\n\tNote: The maximum number of characters is 150. If the commit subject exceeds it, it will be cut, keeping only the first 150 characters.")
}

func newSemantic(logger *log.Log, upgradeVersionCmd *flag.FlagSet, gitHost, groupName, projectName, username, password *string, upgradePyFile *bool) *semantic.Semantic {
func newSemantic(logger *log.Log, upgradeVersionCmd *flag.FlagSet, gitHost, groupName, projectName, username, password *string, upgradePyFile *bool, upgradeType *string) *semantic.Semantic {

validateIncomingParams(logger, upgradeVersionCmd, gitHost, groupName, projectName, username, password, upgradePyFile)

Expand All @@ -197,5 +198,5 @@ func newSemantic(logger *log.Log, upgradeVersionCmd *flag.FlagSet, gitHost, grou

versionControl := v.NewVersionControl(logger, timer.PrintElapsedTime)

return semantic.New(logger, repositoryRootPath, addFilesToUpgradeList(upgradePyFile, repositoryRootPath), repoVersionControl, filesVersionControl, versionControl)
return semantic.New(logger, repositoryRootPath, addFilesToUpgradeList(upgradePyFile, repositoryRootPath), repoVersionControl, filesVersionControl, versionControl, *upgradeType)
}
6 changes: 0 additions & 6 deletions src/files/mock/CHANGELOG_MOCK.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@

## v1.1.0
- feat - [b25a9af](https://gitlab.com/dataplatform/test/commit/b25a9af78c30de0d03ca2ee6d18c66bbc4804395): This is a long message to write to changelog.md file. bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo bar foo ... (@admin)
---


## v1.1.0
- feat - [b25a9af](https://gitlab.com/dataplatform/test/commit/b25a9af78c30de0d03ca2ee6d18c66bbc4804395): This is a short message to write to changelog.md file. (@admin)
---
Expand Down
10 changes: 6 additions & 4 deletions src/semantic/semantic.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type RepositoryVersionControl interface {

type VersionControl interface {
GetCommitChangeType(commitMessage string) (string, error)
GetNewVersion(commitMessage string, currentVersion string) (string, error)
GetNewVersion(commitMessage string, currentVersion string, upgradeType string) (string, error)
MustSkipVersioning(commitMessage string) bool
}

Expand All @@ -54,6 +54,7 @@ type Semantic struct {
repoVersionControl RepositoryVersionControl
versionControl VersionControl
filesVersionControl FilesVersionControl
upgradeType string
}

func (s *Semantic) GenerateNewRelease() error {
Expand All @@ -65,12 +66,12 @@ func (s *Semantic) GenerateNewRelease() error {
CurrentVersion: s.repoVersionControl.GetCurrentVersion(),
}

if s.versionControl.MustSkipVersioning(changesInfo.Message) {
if s.versionControl.MustSkipVersioning(changesInfo.Message) && s.upgradeType == "" {
s.log.Info(colorCyan + "Semantic Release has been skiped by commit message tag [skip]" + colorReset)
return nil
}

newVersion, err := s.versionControl.GetNewVersion(changesInfo.Message, changesInfo.CurrentVersion)
newVersion, err := s.versionControl.GetNewVersion(changesInfo.Message, changesInfo.CurrentVersion, s.upgradeType)
if err != nil {
return errors.New("error while getting new version due to: " + err.Error())
}
Expand Down Expand Up @@ -110,13 +111,14 @@ func (s *Semantic) GenerateNewRelease() error {
return nil
}

func New(log Logger, rootPath string, filesToUpdateVariable interface{}, repoVersionControl RepositoryVersionControl, filesVersionControl FilesVersionControl, versionControl VersionControl) *Semantic {
func New(log Logger, rootPath string, filesToUpdateVariable interface{}, repoVersionControl RepositoryVersionControl, filesVersionControl FilesVersionControl, versionControl VersionControl, upgradeType string) *Semantic {
return &Semantic{
log: log,
rootPath: rootPath,
filesToUpdateVariable: filesToUpdateVariable,
repoVersionControl: repoVersionControl,
filesVersionControl: filesVersionControl,
versionControl: versionControl,
upgradeType: upgradeType,
}
}
5 changes: 3 additions & 2 deletions src/semantic/semantic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (v *VersionControlMock) GetCommitChangeType(commitMessage string) (string,
return v.commitChangeType, v.errCommitChangeType
}

func (v *VersionControlMock) GetNewVersion(commitMessage string, currentVersion string) (string, error) {
func (v *VersionControlMock) GetNewVersion(commitMessage string, currentVersion string, upgradeType string) (string, error) {
return v.newVersion, v.errGetNewVersion
}

Expand Down Expand Up @@ -93,7 +93,8 @@ func (f *fixture) NewSemantic() *semantic.Semantic {
errors.New("error while getting new log")
}

return semantic.New(logger, f.rootPath, f.filesToUpdateVariable, f.repoVersionMock, f.filesVersionMock, f.versionControlMock)
version := ""
return semantic.New(logger, f.rootPath, f.filesToUpdateVariable, f.repoVersionMock, f.filesVersionMock, f.versionControlMock, version)
}

type upgradeFilesMock struct {
Expand Down
113 changes: 69 additions & 44 deletions src/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ const (
)

var (
commitChangeTypes = []string{"build", "ci", "docs", "fix", "feat", "perf", "refactor", "style", "test", "breaking change", "breaking changes", "skip", "skip versioning", "skip v"}
commitChangeTypesMajorUpgrade = []string{"breaking change", "breaking changes"}
commitChangeTypesMinorUpgrade = []string{"feat"}
commitChangeTypePatchUpgrade = []string{"build", "ci", "docs", "fix", "perf", "refactor", "style", "test"}
commitChangeTypes = []string{"build", "ci", "docs", "fix", "feat", "perf", "refactor", "style", "test", "breaking change", "breaking changes", "skip", "skip versioning", "skip v", "major", "minor", "patch"}
commitChangeTypesMajorUpgrade = []string{"breaking change", "breaking changes", "major"}
commitChangeTypesMinorUpgrade = []string{"feat", "minor"}
commitChangeTypePatchUpgrade = []string{"build", "ci", "docs", "fix", "perf", "refactor", "style", "test", "patch"}
commitTypeSkipVersioning = []string{"skip", "skip versioning", "skip v"}
)

Expand All @@ -37,14 +37,17 @@ type VersionControl struct {

// splitVersionMajorMinorPatch get a string version, split it and return a map of int values
// Args:
// version (string): Version to be splited. I.e: 2.1.1
//
// version (string): Version to be splited. I.e: 2.1.1
//
// Returns:
// Success:
// It returns a map of int values
// I.e.: map[MAJOR:2 MINOR:1 PATCH:1]
//
// Otherwise:
// error
// Success:
// It returns a map of int values
// I.e.: map[MAJOR:2 MINOR:1 PATCH:1]
//
// Otherwise:
// error
func (v *VersionControl) splitVersionMajorMinorPatch(version string) (map[string]int, error) {
splitedVersion := strings.Split(version, ".")

Expand Down Expand Up @@ -74,12 +77,15 @@ func (v *VersionControl) splitVersionMajorMinorPatch(version string) (map[string
// getUpgradeType defines where to update the current version
// MAJOR.MINOR.PATCH. I.e: 2.1.1
// Args:
// commitChangeType (string): Type of changes within the commit. I.e.: fix, feat, doc, etc. Take a look at CommitChangeTypes variable.
//
// commitChangeType (string): Type of changes within the commit. I.e.: fix, feat, doc, etc. Take a look at CommitChangeTypes variable.
//
// Returns:
// MAJOR: if the commit type is in CommitChangeTypesMajorUpgrade slice
// MINOR: if the commit type is in CommitChangeTypesMinorUpgrade slice
// PATCH: if the commit type is in CommitChangeTypePatchUpgrade slice
// Otherwise, it returns an error
//
// MAJOR: if the commit type is in CommitChangeTypesMajorUpgrade slice
// MINOR: if the commit type is in CommitChangeTypesMinorUpgrade slice
// PATCH: if the commit type is in CommitChangeTypePatchUpgrade slice
// Otherwise, it returns an error
func (v *VersionControl) getUpgradeType(commitChangeType string) (string, error) {
if v.hasStringInSlice(commitChangeType, commitChangeTypesMajorUpgrade) {
return major, nil
Expand All @@ -93,16 +99,19 @@ func (v *VersionControl) getUpgradeType(commitChangeType string) (string, error)

// upgradeVersion upgrade the current version based on the upgradeType.
// Args:
// upgradeType (string): MAJOR, MINOR or PATCH.
// currentMajor (string): Current release major version. I.e.: >2<.1.1.
// currentMinor (string): Current release minor version. I.e.: 2.>1<.1.
// currentPatch (string): Current release patch version. I.e.: 2.1.>1<.
//
// upgradeType (string): MAJOR, MINOR or PATCH.
// currentMajor (string): Current release major version. I.e.: >2<.1.1.
// currentMinor (string): Current release minor version. I.e.: 2.>1<.1.
// currentPatch (string): Current release patch version. I.e.: 2.1.>1<.
//
// Returns:
// It will return a string with the new version.
// I.e.:
// 1 - If the current version is 2.1.1 and the update type is MAJOR it will return 3.0.0
// 2 - If the current version is 2.1.1 and the update type is MINOR it will return 2.2.0
// 1 - If the current version is 2.1.1 and the update type is PATCH it will return 2.1.2
//
// It will return a string with the new version.
// I.e.:
// 1 - If the current version is 2.1.1 and the update type is MAJOR it will return 3.0.0
// 2 - If the current version is 2.1.1 and the update type is MINOR it will return 2.2.0
// 1 - If the current version is 2.1.1 and the update type is PATCH it will return 2.1.2
func (v *VersionControl) upgradeVersion(upgradeType string, currentMajor, currentMinor, currentPatch int) string {
versionPattern := "%d.%d.%d"
var newVersion string
Expand Down Expand Up @@ -131,22 +140,31 @@ func (v *VersionControl) isFirstVersion(version string) bool {
// GetNewVersion upgrade the current version based on the commitChangeType.
// It calls the getUpgradeType function to define where to upgrade the version (MAJOR.MINOR.PATCH).
// Args:
// commitMessage (string): The commit message.
// currentVersion (string): Current release version. I.e.: 2.1.1.
//
// commitMessage (string): The commit message.
// currentVersion (string): Current release version. I.e.: 2.1.1.
//
// Returns:
// string: It will return a string with the new version.
// I.e.:
// 1 - If the current version is 2.1.1 and the update type is MAJOR it will return 3.0.0
// 2 - If the current version is 2.1.1 and the update type is MINOR it will return 2.2.0
// 1 - If the current version is 2.1.1 and the update type is PATCH it will return 2.1.2
// error: It returns an error when something wrong happen.
func (v *VersionControl) GetNewVersion(commitMessage string, currentVersion string) (string, error) {
//
// string: It will return a string with the new version.
// I.e.:
// 1 - If the current version is 2.1.1 and the update type is MAJOR it will return 3.0.0
// 2 - If the current version is 2.1.1 and the update type is MINOR it will return 2.2.0
// 1 - If the current version is 2.1.1 and the update type is PATCH it will return 2.1.2
// error: It returns an error when something wrong happen.
func (v *VersionControl) GetNewVersion(commitMessage string, currentVersion string, upgradeType string) (string, error) {
defer v.printElapsedTime("GetNewVersion")()
v.log.Info("generating new version from %s", currentVersion)

commitChangeType, err := v.GetCommitChangeType(commitMessage)
if err != nil {
return "", fmt.Errorf("error while finding commit change type within commit message due to: %w", err)
var commitChangeType string
var err error
if upgradeType == "" {
commitChangeType, err = v.GetCommitChangeType(commitMessage)
if err != nil {
return "", fmt.Errorf("error while finding commit change type within commit message due to: %w", err)
}
} else {
commitChangeType = upgradeType
}

curVersion, err := v.splitVersionMajorMinorPatch(currentVersion)
Expand All @@ -157,12 +175,12 @@ func (v *VersionControl) GetNewVersion(commitMessage string, currentVersion stri
currentMinor := curVersion[minor]
currentPatch := curVersion[patch]

upgradeType, err := v.getUpgradeType(commitChangeType)
commitUpgradeType, err := v.getUpgradeType(commitChangeType)
if err != nil {
return "", fmt.Errorf("error while getting upgrade type due to: %w", err)
}

newVersion := v.upgradeVersion(upgradeType, currentMajor, currentMinor, currentPatch)
newVersion := v.upgradeVersion(commitUpgradeType, currentMajor, currentMinor, currentPatch)
if v.isFirstVersion(newVersion) {
return "1.0.0", nil
}
Expand All @@ -172,8 +190,10 @@ func (v *VersionControl) GetNewVersion(commitMessage string, currentVersion stri

// GetCommitChangeType get the commit type from Message
// I.e.:
// type: [fix]
// message: Commit subject here.
//
// type: [fix]
// message: Commit subject here.
//
// Output: fix
func (v *VersionControl) GetCommitChangeType(commitMessage string) (string, error) {
v.log.Info("getting commit type from message %s", commitMessage)
Expand All @@ -192,10 +212,13 @@ func (v *VersionControl) GetCommitChangeType(commitMessage string) (string, erro
// hasStringInSlice aims to verify if a string is inside a slice of strings.
// It requires a full match.
// Args:
// value (string): String value to find.
// slice ([]string): Slice containing strings.
//
// value (string): String value to find.
// slice ([]string): Slice containing strings.
//
// Returns:
// bool: True when found, otherwise false.
//
// bool: True when found, otherwise false.
func (v *VersionControl) hasStringInSlice(value string, slice []string) bool {
for i := range slice {
if slice[i] == value {
Expand All @@ -207,7 +230,9 @@ func (v *VersionControl) hasStringInSlice(value string, slice []string) bool {

// MustSkip compare commit type with skip types (CommitTypeSkipVersioning) to avoid upgrading version.
// I.e.:
// commitChangeType: [skip]
//
// commitChangeType: [skip]
//
// Output: true
func (v *VersionControl) MustSkipVersioning(commitMessage string) bool {
commitChangeType, err := v.GetCommitChangeType(commitMessage)
Expand Down
Loading
Loading