Skip to content

Commit

Permalink
feat: Support for patterns matching Conventional Commit types for bu… (
Browse files Browse the repository at this point in the history
…#179)

* feat:  Support for patterns matching Conventional Commit types for bumping versions.  
* feat:  Adding dyn-ver to build
* feat:  Conventional commits are additive by default when enabled, can be toggled to singular via a new setting key 'conventionalPatternsAdditive'
  • Loading branch information
dkichler authored Mar 16, 2023
1 parent 1308459 commit 96e1a59
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 1 deletion.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,26 @@ If set to `None`, an error will be thrown, and the release will be aborted.

Set to `Some(Bump.Bugfix)` by default.

## Conventional Commits

An additional opt-in plugin is also provided that overrides the default bump patterns with those modelled after the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec:

* major: `.*BREAKING[-\s]CHANGE: .*`, `^(.*!: ).*`
* minor: `^feat.*: .*`
* bugfix: `^fix.*: .*`

The plugin must be manually enabled to take effect in `built.sbt`:

```
enablePlugins(AutoVersionPlugin, ConventionalCommits)
```

_Note_: By default these patterns are applied _in addition_ to the default patterns, so that commit messages will match either the default or conventional commit patterns. This default behavior can be disabled with this setting key, enabling _only_ Conventional commit patterns:

```
conventionalPatternsAdditive := false
```

# License

This software is under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0.html).
1 change: 1 addition & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.14.2")
addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.11")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.0")
addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1")
2 changes: 1 addition & 1 deletion src/main/scala/autoversion/AutoVersionPlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import autoversion.model.{Commit, Tag}
import com.github.sbt.git.{GitPlugin, SbtGit}
import com.vdurmont.semver4j.Semver
import com.vdurmont.semver4j.Semver.SemverType
import sbt.*
import sbt.{AutoPlugin, Def, Logger, PluginTrigger, Plugins, Setting, file}
import sbtrelease.ReleasePlugin
import sbtrelease.ReleasePlugin.autoImport.releaseVersion
import sbtrelease.Version.Bump
Expand Down
3 changes: 3 additions & 0 deletions src/main/scala/autoversion/Keys.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@ object Keys {
val defaultBump = settingKey[Option[Bump]](
"Default version bump if sbt-autoversion is unable to suggest one based on commit messages."
)
val conventionalPatternsAdditive = settingKey[Boolean](
"A flag for controlling whether Conventional Commits are applied additionally to the default patterns, or override them completely. Defaults to true"
)
}
39 changes: 39 additions & 0 deletions src/main/scala/autoversion/conventional/ConventionalCommits.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package autoversion.conventional

import autoversion.AutoVersionPlugin
import autoversion.Keys.{bugfixRegexes, conventionalPatternsAdditive, majorRegexes, minorRegexes}
import sbt.{AutoPlugin, Setting, settingKey}

/**
* An additional opt-in plugin that enables Conventional Commit style patterns for bumping the version
*/
object ConventionalCommits extends AutoPlugin {

override def requires = AutoVersionPlugin

override def projectSettings: Seq[Setting[_]] =
Seq(
conventionalPatternsAdditive := true,
majorRegexes := {
val conventionalMajor = Seq(""".*BREAKING[-\s]CHANGE: .*""".r, "^(.*!: ).*".r)
if (conventionalPatternsAdditive.value)
conventionalMajor ++ majorRegexes.value
else
conventionalMajor
},
minorRegexes := {
val conventionalMinor = Seq("^feat.*: .*".r)
if (conventionalPatternsAdditive.value)
conventionalMinor ++ minorRegexes.value
else
conventionalMinor
},
bugfixRegexes := {
val conventionalBugfix = Seq("^feat.*: .*".r)
if (conventionalPatternsAdditive.value)
conventionalBugfix ++ bugfixRegexes.value
else
conventionalBugfix
}
)
}
3 changes: 3 additions & 0 deletions src/sbt-test/sbt-autoversion/conventional-commits/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target
global
project/build.properties
19 changes: 19 additions & 0 deletions src/sbt-test/sbt-autoversion/conventional-commits/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import ReleaseTransformations._

Global / onChangedBuildSource := ReloadOnSourceChanges

enablePlugins(AutoVersionPlugin, ConventionalCommits)
// Default sbt-release process, minus publication (for testing).
releaseProcess := Seq[ReleaseStep](
checkSnapshotDependencies,
inquireVersions,
runClean,
runTest,
setReleaseVersion,
commitReleaseVersion,
tagRelease,
// publishArtifacts,
setNextVersion,
commitNextVersion
// pushChanges
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
sys.props.get("plugin.version") match {
case Some(version) => addSbtPlugin("com.github.sbt" % "sbt-autoversion" % version)
case _ => sys.error("""|The system property 'plugin.version' is not defined.
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin)
}
118 changes: 118 additions & 0 deletions src/sbt-test/sbt-autoversion/conventional-commits/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Generate project files.
> reload
> compile

# Setup repository.
$ exec git init
$ exec git config user.email "email"
$ exec git config user.name "name"
$ exec git add .
$ exec git commit -m 'initial commit'
$ exec git tag v0.0.0

# Prove sbt can start.
> reload
> compile
> show version
> plugins
> show minorRegexes

# 0.0.0 => 0.0.1 => 0.0.2-SNAPSHOT
$ exec git commit --allow-empty -m 'fix: foobar'
> reload
> release with-defaults
$ exec grep -Fq '"0.0.2-SNAPSHOT"' version.sbt

# 0.0.2-SNAPSHOT => 0.0.2 => 0.0.3-SNAPSHOT
$ exec git commit --allow-empty -m 'fix(with-scope): foobar'
> reload
> release with-defaults
$ exec grep -Fq '"0.0.3-SNAPSHOT"' version.sbt

# 0.0.3-SNAPSHOT => 0.1.0 => 0.1.1-SNAPSHOT
$ exec git commit --allow-empty -m 'feat: foobar'
> reload
> release with-defaults
$ exec grep -Fq '"0.1.1-SNAPSHOT"' version.sbt

# 0.1.1-SNAPSHOT => 0.1.1 => 0.1.2-SNAPSHOT
$ exec git commit --allow-empty -m 'fix(issues): foobar'
> reload
> release with-defaults
$ exec grep -Fq '"0.1.2-SNAPSHOT"' version.sbt

# 0.1.2-SNAPSHOT => 0.2.0 => 0.2.1-SNAPSHOT
$ exec git commit --allow-empty -m 'feat(issue 13): foobar'
> reload
> release with-defaults
$ exec grep -Fq '"0.2.1-SNAPSHOT"' version.sbt

# breaking change somewhere in the commit
# 0.2.1-SNAPSHOT => 1.0.0 => 1.0.1-SNAPSHOT
$ exec git commit --allow-empty -m 'refactor: rewrote service\n BREAKING CHANGE: changed the API'
> reload
> release with-defaults
$ exec grep -Fq '"1.0.1-SNAPSHOT"' version.sbt

# 1.0.1-SNAPSHOT => 1.0.1 => 1.0.2-SNAPSHOT
$ exec git commit --allow-empty -m 'fix: foobar'
> reload
> release with-defaults
$ exec grep -Fq '"1.0.2-SNAPSHOT"' version.sbt

# 1.0.2-SNAPSHOT => 2.0.0 => 2.0.1-SNAPSHOT
$ exec git commit --allow-empty -m 'feat(scope)!: foobar'
> reload
> release with-defaults
$ exec grep -Fq '"2.0.1-SNAPSHOT"' version.sbt

# Test that default patterns are still active (ConventionalCommit patterns additive by default)
# 2.0.1-SNAPSHOT => 2.0.1 => 2.0.2-SNAPSHOT
$ exec git commit --allow-empty -m 'bugfix: foobar'
> reload
> release with-defaults
$ exec grep -Fq '"2.0.2-SNAPSHOT"' version.sbt

# 2.0.2-SNAPSHOT => 2.1.0 => 2.1.1-SNAPSHOT
$ exec git commit --allow-empty -m 'minor: foobar'
> reload
> release with-defaults
$ exec grep -Fq '"2.1.1-SNAPSHOT"' version.sbt

# 2.1.1-SNAPSHOT => 3.0.0 => 3.0.1-SNAPSHOT
$ exec git commit --allow-empty -m 'major: foobar'
> reload
> release with-defaults
$ exec grep -Fq '"3.0.1-SNAPSHOT"' version.sbt

# Now disable additive ConventionalCommit patterns and test that default patterns do not apply
# Default patch level bump pattern should fail
$ exec git commit --allow-empty -m 'bugfix: foobar'
> reload
> set conventionalPatternsAdditive := false
# disable default bump to assert patterns are _not_ matching
> set defaultBump := None
-> release with-defaults

# Default minor level bump pattern should fail
$ exec git commit --amend --allow-empty -m 'minor: foobar'
> reload
> set conventionalPatternsAdditive := false
> set defaultBump := None
-> release with-defaults

# Default major level bump pattern should fail
$ exec git commit --amend --allow-empty -m 'major: foobar'
> reload
> set conventionalPatternsAdditive := false
> set defaultBump := None
-> release with-defaults

# But CC ones do
# 3.0.1-SNAPSHOT => 3.1.0 => 3.1.1-SNAPSHOT
$ exec git commit --allow-empty -m 'feat: foobar'
> reload
> set conventionalPatternsAdditive := false
> set defaultBump := None
> release with-defaults
$ exec grep -Fq '"3.1.1-SNAPSHOT"' version.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ThisBuild / version := "0.0.0"
2 changes: 2 additions & 0 deletions src/sbt-test/sbt-autoversion/simple/build.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import ReleaseTransformations._

Global / onChangedBuildSource := ReloadOnSourceChanges

// Default sbt-release process, minus publication (for testing).
releaseProcess := Seq[ReleaseStep](
checkSnapshotDependencies,
Expand Down

0 comments on commit 96e1a59

Please sign in to comment.