diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 07a81aedd72b8062a5c42e7446d4d90770182032..15ec1324dbadcb09ef056a5898b31c81196fcbd7 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -13,7 +13,7 @@ jobs:
       - uses: actions/checkout@v4
       - uses: actions/setup-go@v4
         with:
-          go-version: '1.21'
+          go-version: '1.22'
       - uses: golangci/golangci-lint-action@v3
   build:
     runs-on: ${{ matrix.os }}
@@ -26,7 +26,7 @@ jobs:
       - uses: actions/checkout@v4
       - uses: actions/setup-go@v4
         with:
-          go-version: '1.21'
+          go-version: '1.22'
       - run: go build ./cmd/commit-analyzer-cz/
       - run: go test -v ./...
   release:
@@ -36,7 +36,7 @@ jobs:
       - uses: actions/checkout@v4
       - uses: actions/setup-go@v4
         with:
-          go-version: '1.21'
+          go-version: '1.22'
       - uses: go-semantic-release/action@v1
         with:
           hooks: goreleaser,plugin-registry-update
diff --git a/go.mod b/go.mod
index 62d51d8b3b7c432f712635154bb9f0fefb7dda53..66599481ccdcc74f28ae0e7df5f0130d72069c3b 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module github.com/go-semantic-release/commit-analyzer-cz
 
-go 1.21
+go 1.22
 
 require (
 	github.com/go-semantic-release/semantic-release/v2 v2.28.0
diff --git a/pkg/analyzer/commit_analyzer.go b/pkg/analyzer/commit_analyzer.go
index 400dd5309c744f64a3ea1fe1a476707d2815c67d..67038a0bb4282d7064d92ccf31bed9a5a4be44c1 100644
--- a/pkg/analyzer/commit_analyzer.go
+++ b/pkg/analyzer/commit_analyzer.go
@@ -1,6 +1,8 @@
 package analyzer
 
 import (
+	"cmp"
+	"fmt"
 	"strings"
 
 	"github.com/go-semantic-release/semantic-release/v2/pkg/semrel"
@@ -8,10 +10,26 @@ import (
 
 var CAVERSION = "dev"
 
-type DefaultCommitAnalyzer struct{}
+type DefaultCommitAnalyzer struct {
+	majorReleaseRules releaseRules
+	minorReleaseRules releaseRules
+	patchReleaseRules releaseRules
+}
 
 func (da *DefaultCommitAnalyzer) Init(m map[string]string) error {
-	// TODO: implement config parsing
+	var err error
+	da.majorReleaseRules, err = parseRules(cmp.Or(m["major_release_rules"], defaultMajorReleaseRules))
+	if err != nil {
+		return fmt.Errorf("failed to parse major release rules: %w", err)
+	}
+	da.minorReleaseRules, err = parseRules(cmp.Or(m["minor_release_rules"], defaultMinorReleaseRules))
+	if err != nil {
+		return fmt.Errorf("failed to parse minor release rules: %w", err)
+	}
+	da.patchReleaseRules, err = parseRules(cmp.Or(m["patch_release_rules"], defaultPatchReleaseRules))
+	if err != nil {
+		return fmt.Errorf("failed to parse patch release rules: %w", err)
+	}
 	return nil
 }
 
@@ -24,21 +42,20 @@ func (da *DefaultCommitAnalyzer) Version() string {
 }
 
 func (da *DefaultCommitAnalyzer) setTypeAndChange(c *semrel.Commit) {
-	found := commitPattern.FindAllStringSubmatch(c.Raw[0], -1)
-	if len(found) < 1 {
-		// commit message does not match pattern
+	pc := parseCommit(c.Raw[0])
+	if pc == nil {
 		return
 	}
 
-	c.Type = strings.ToLower(found[0][1])
-	c.Scope = found[0][2]
-	c.Message = found[0][4]
+	c.Type = pc.Type
+	c.Scope = pc.Scope
+	c.Message = pc.Message
 
 	c.Change = &semrel.Change{
 		// either uses the `!` convention or has a breaking change section
-		Major: found[0][3] == "!" || matchesBreakingPattern(c),
-		Minor: c.Type == "feat",
-		Patch: c.Type == "fix",
+		Major: da.majorReleaseRules.Matches(pc) || matchesBreakingPattern(c),
+		Minor: da.minorReleaseRules.Matches(pc),
+		Patch: da.patchReleaseRules.Matches(pc),
 	}
 }
 
diff --git a/pkg/analyzer/commit_analyzer_test.go b/pkg/analyzer/commit_analyzer_test.go
index 0173bc32f64bd52ea34eafc5830e0fba4caffd1c..4b8c80af279241ac3d4ab1924aeb0aa08de31744 100644
--- a/pkg/analyzer/commit_analyzer_test.go
+++ b/pkg/analyzer/commit_analyzer_test.go
@@ -20,6 +20,7 @@ func createRawCommit(sha, message string) *semrel.RawCommit {
 
 func TestAnnotations(t *testing.T) {
 	defaultAnalyzer := &DefaultCommitAnalyzer{}
+	require.NoError(t, defaultAnalyzer.Init(map[string]string{}))
 	rawCommit := createRawCommit("a", "fix: bug #123 and #243\nthanks @Test-user for providing this fix\n\nCloses #22")
 	commit := defaultAnalyzer.analyzeSingleCommit(rawCommit)
 	require.Equal(t, rawCommit.SHA, commit.SHA)
@@ -64,13 +65,13 @@ func TestDefaultAnalyzer(t *testing.T) {
 			createRawCommit("e", "feat!: modified login endpoint"),
 			"feat",
 			"",
-			&semrel.Change{Major: true, Minor: true, Patch: false},
+			&semrel.Change{Major: true, Minor: false, Patch: false},
 		},
 		{
 			createRawCommit("f", "fix!: fixed a typo"),
 			"fix",
 			"",
-			&semrel.Change{Major: true, Minor: false, Patch: true},
+			&semrel.Change{Major: true, Minor: false, Patch: false},
 		},
 		{
 			createRawCommit("g", "refactor(parser)!: drop support for Node 6\n\nBREAKING CHANGE: refactor to use JavaScript features not available in Node 6."),
@@ -99,6 +100,7 @@ func TestDefaultAnalyzer(t *testing.T) {
 	}
 
 	defaultAnalyzer := &DefaultCommitAnalyzer{}
+	require.NoError(t, defaultAnalyzer.Init(map[string]string{}))
 	for _, tc := range testCases {
 		t.Run(tc.RawCommit.RawMessage, func(t *testing.T) {
 			analyzedCommit := defaultAnalyzer.analyzeSingleCommit(tc.RawCommit)
diff --git a/pkg/analyzer/rules.go b/pkg/analyzer/rules.go
index bb2ef7aaba984957b7ade182f128f45633b47ba2..aa94d9b7f93267a7232efde258871d36f7e26220 100644
--- a/pkg/analyzer/rules.go
+++ b/pkg/analyzer/rules.go
@@ -7,7 +7,7 @@ import (
 )
 
 var (
-	defaultMajorReleaseRules = "*(*)!"
+	defaultMajorReleaseRules = "*!"
 	defaultMinorReleaseRules = "feat"
 	defaultPatchReleaseRules = "fix"
 )