0
# Version Management
1
2
Comprehensive version management with support for semantic versioning, PEP 440, automatic file updates, and multiple version schemes. Commitizen provides intelligent version bumping based on commit history analysis and supports various versioning standards used across different ecosystems.
3
4
## Capabilities
5
6
### Version Increment Detection
7
8
Analyzes commit history to determine appropriate version increment based on commit message patterns.
9
10
```python { .api }
11
def find_increment(
12
commits: list[GitCommit],
13
regex: Pattern[str],
14
incremental_rev: str = ""
15
) -> str:
16
"""
17
Determine version increment type from commit history.
18
19
Analyzes commits using the provided regex pattern to identify
20
BREAKING changes, features, and fixes to determine if version
21
should be bumped MAJOR, MINOR, or PATCH.
22
23
Parameters:
24
- commits: List of git commits to analyze
25
- regex: Compiled regex pattern for parsing commit messages
26
- incremental_rev: Starting revision for analysis
27
28
Returns:
29
Version increment type: "MAJOR", "MINOR", "PATCH", or None
30
"""
31
```
32
33
### Version File Updates
34
35
Updates version information across multiple files in the project automatically.
36
37
```python { .api }
38
def update_version_in_files(
39
current_version: str,
40
new_version: str,
41
files: list[str]
42
) -> None:
43
"""
44
Update version strings in specified files.
45
46
Supports various file formats and version string patterns:
47
- Python files: __version__ = "1.0.0"
48
- JSON files: "version": "1.0.0"
49
- TOML files: version = "1.0.0"
50
- Plain text files: version replacement
51
52
Parameters:
53
- current_version: Current version string to replace
54
- new_version: New version string
55
- files: List of file paths, optionally with specific keys (file.json:version)
56
"""
57
```
58
59
### Tag Normalization
60
61
Normalizes git tag names according to configured format templates.
62
63
```python { .api }
64
def normalize_tag(tag: str, tag_format: str) -> str:
65
"""
66
Normalize tag name according to format template.
67
68
Converts between different tag formats and ensures consistency
69
with configured tag_format setting.
70
71
Parameters:
72
- tag: Original tag name
73
- tag_format: Tag format template (e.g., "v$version", "$version")
74
75
Returns:
76
Normalized tag name
77
"""
78
```
79
80
### Version Schemes
81
82
#### Version Protocol
83
84
Interface definition for all version scheme implementations.
85
86
```python { .api }
87
class VersionProtocol(Protocol):
88
"""Protocol defining the interface for version schemes."""
89
90
def parse(self, version: str) -> Any:
91
"""
92
Parse version string into version object.
93
94
Parameters:
95
- version: Version string to parse
96
97
Returns:
98
Parsed version object
99
"""
100
101
def bump(self, version: Any, increment: str) -> Any:
102
"""
103
Bump version by specified increment.
104
105
Parameters:
106
- version: Parsed version object
107
- increment: Increment type (MAJOR, MINOR, PATCH)
108
109
Returns:
110
Bumped version object
111
"""
112
113
def serialize(self, version: Any) -> str:
114
"""
115
Serialize version object to string.
116
117
Parameters:
118
- version: Version object to serialize
119
120
Returns:
121
Version string
122
"""
123
```
124
125
#### Base Version Class
126
127
Abstract base implementation providing common version functionality.
128
129
```python { .api }
130
class BaseVersion:
131
"""Abstract base class for version implementations."""
132
133
def __init__(self, version_string: str):
134
"""
135
Initialize version from string.
136
137
Parameters:
138
- version_string: Version string to parse
139
"""
140
141
def bump(self, increment: str) -> "BaseVersion":
142
"""
143
Create new version with specified increment.
144
145
Parameters:
146
- increment: Increment type (MAJOR, MINOR, PATCH)
147
148
Returns:
149
New version instance
150
"""
151
152
def __str__(self) -> str:
153
"""Return string representation of version."""
154
155
def __eq__(self, other: Any) -> bool:
156
"""Compare versions for equality."""
157
158
def __lt__(self, other: Any) -> bool:
159
"""Compare versions for ordering."""
160
```
161
162
#### PEP 440 Version Scheme
163
164
Python ecosystem version scheme following PEP 440 specification.
165
166
```python { .api }
167
class Pep440(BaseVersion):
168
"""
169
PEP 440 version scheme for Python packages.
170
171
Supports development releases, pre-releases, post-releases, and local versions.
172
Format examples: 1.0.0, 1.0.0a1, 1.0.0b2, 1.0.0rc1, 1.0.0.post1, 1.0.0+local
173
"""
174
def parse(self, version: str) -> dict[str, Any]:
175
"""
176
Parse PEP 440 version string.
177
178
Returns:
179
Dictionary with version components (major, minor, patch, pre, post, local)
180
"""
181
182
def bump(self, version: dict[str, Any], increment: str) -> dict[str, Any]:
183
"""
184
Bump PEP 440 version.
185
186
Handles pre-release and post-release versioning according to PEP 440.
187
"""
188
189
def serialize(self, version: dict[str, Any]) -> str:
190
"""Serialize PEP 440 version to string."""
191
```
192
193
#### Semantic Versioning
194
195
Standard semantic versioning scheme (semver.org).
196
197
```python { .api }
198
class SemVer(BaseVersion):
199
"""
200
Semantic versioning scheme (semver.org).
201
202
Format: MAJOR.MINOR.PATCH[-PRERELEASE][+BUILD]
203
Example: 1.0.0, 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0+build.1
204
"""
205
def parse(self, version: str) -> dict[str, Any]:
206
"""
207
Parse semantic version string.
208
209
Returns:
210
Dictionary with version components (major, minor, patch, prerelease, build)
211
"""
212
213
def bump(self, version: dict[str, Any], increment: str) -> dict[str, Any]:
214
"""
215
Bump semantic version.
216
217
Follows semantic versioning rules for pre-release handling.
218
"""
219
220
def serialize(self, version: dict[str, Any]) -> str:
221
"""Serialize semantic version to string."""
222
```
223
224
#### Alternative Semantic Versioning
225
226
Alternative semantic versioning implementation with different pre-release handling.
227
228
```python { .api }
229
class SemVer2(BaseVersion):
230
"""
231
Alternative semantic versioning with different pre-release rules.
232
233
Similar to SemVer but with alternative handling of pre-release versions.
234
"""
235
def parse(self, version: str) -> dict[str, Any]:
236
"""Parse alternative semantic version string."""
237
238
def bump(self, version: dict[str, Any], increment: str) -> dict[str, Any]:
239
"""Bump alternative semantic version."""
240
241
def serialize(self, version: dict[str, Any]) -> str:
242
"""Serialize alternative semantic version to string."""
243
```
244
245
### Version Scheme Management
246
247
```python { .api }
248
KNOWN_SCHEMES: dict[str, type[BaseVersion]]
249
"""Dictionary of available version schemes."""
250
251
DEFAULT_SCHEME: str
252
"""Default version scheme name."""
253
254
def get_version_scheme(name: str = "pep440") -> VersionProtocol:
255
"""
256
Get version scheme instance by name.
257
258
Parameters:
259
- name: Version scheme name (pep440, semver, semver2)
260
261
Returns:
262
Version scheme instance implementing VersionProtocol
263
264
Raises:
265
ValueError: If version scheme is not found
266
"""
267
```
268
269
### Type Definitions
270
271
```python { .api }
272
Increment = Literal["MAJOR", "MINOR", "PATCH"]
273
"""Type alias for version increment types."""
274
275
Prerelease = Literal["alpha", "beta", "rc"]
276
"""Type alias for pre-release identifiers."""
277
```
278
279
## Usage Examples
280
281
### Basic Version Management
282
283
```python
284
from commitizen.bump import find_increment, update_version_in_files
285
from commitizen.version_schemes import get_version_scheme
286
from commitizen.git import get_commits
287
import re
288
289
# Analyze commits for version increment
290
commits = get_commits(start="v1.0.0", end="HEAD")
291
pattern = re.compile(r"^(feat|fix|BREAKING)")
292
increment = find_increment(commits, pattern)
293
294
print(f"Recommended increment: {increment}") # "MINOR"
295
296
# Update version in files
297
update_version_in_files(
298
current_version="1.0.0",
299
new_version="1.1.0",
300
files=[
301
"src/__version__.py",
302
"pyproject.toml:version",
303
"package.json:version"
304
]
305
)
306
```
307
308
### Working with Version Schemes
309
310
```python
311
from commitizen.version_schemes import get_version_scheme
312
313
# PEP 440 version scheme
314
pep440 = get_version_scheme("pep440")
315
version = pep440.parse("1.0.0")
316
new_version = pep440.bump(version, "MINOR")
317
print(pep440.serialize(new_version)) # "1.1.0"
318
319
# Semantic versioning
320
semver = get_version_scheme("semver")
321
version = semver.parse("1.0.0-alpha.1")
322
new_version = semver.bump(version, "PATCH")
323
print(semver.serialize(new_version)) # "1.0.0"
324
325
# Pre-release versions
326
version = semver.parse("1.0.0")
327
prerelease = semver.bump(version, "PRERELEASE")
328
print(semver.serialize(prerelease)) # "1.0.1-alpha.1"
329
```
330
331
### Custom Version Scheme
332
333
```python
334
from commitizen.version_schemes import BaseVersion
335
from typing import Any
336
337
class CustomVersion(BaseVersion):
338
"""Custom version scheme for internal projects."""
339
340
def parse(self, version: str) -> dict[str, Any]:
341
# Parse custom format: YEAR.MONTH.BUILD
342
parts = version.split('.')
343
return {
344
"year": int(parts[0]),
345
"month": int(parts[1]),
346
"build": int(parts[2]) if len(parts) > 2 else 0
347
}
348
349
def bump(self, version: dict[str, Any], increment: str) -> dict[str, Any]:
350
from datetime import datetime
351
now = datetime.now()
352
353
if increment == "MAJOR":
354
return {"year": now.year, "month": now.month, "build": 0}
355
elif increment == "MINOR":
356
return {
357
"year": version["year"],
358
"month": now.month,
359
"build": 0
360
}
361
else: # PATCH
362
return {
363
"year": version["year"],
364
"month": version["month"],
365
"build": version["build"] + 1
366
}
367
368
def serialize(self, version: dict[str, Any]) -> str:
369
return f"{version['year']}.{version['month']}.{version['build']}"
370
371
# Register custom scheme
372
custom = CustomVersion("2024.1.0")
373
new_version = custom.bump(custom.parse("2024.1.5"), "PATCH")
374
print(str(new_version)) # "2024.1.6"
375
```
376
377
### Version Provider Integration
378
379
```python
380
from commitizen.providers import get_provider
381
382
# Get version from different sources
383
poetry_provider = get_provider("poetry")
384
current_version = poetry_provider.get_version()
385
386
npm_provider = get_provider("npm")
387
npm_version = npm_provider.get_version()
388
389
# Update version in provider
390
poetry_provider.set_version("2.0.0")
391
npm_provider.set_version("2.0.0")
392
```
393
394
### Configuration-Driven Version Management
395
396
```toml
397
[tool.commitizen]
398
version_scheme = "semver"
399
version_files = [
400
"src/__version__.py",
401
"pyproject.toml:version",
402
"package.json:version",
403
"VERSION"
404
]
405
406
# Custom bump patterns
407
bump_pattern = "^(feat|fix|BREAKING|perf)"
408
bump_map = {
409
"BREAKING" = "MAJOR",
410
"feat" = "MINOR",
411
"fix" = "PATCH",
412
"perf" = "PATCH"
413
}
414
415
# Major version zero handling
416
major_version_zero = true
417
bump_map_major_version_zero = {
418
"BREAKING" = "MINOR",
419
"feat" = "PATCH",
420
"fix" = "PATCH"
421
}
422
```