Python Semantic Release
python-semantic-release automates semantic versioning, changelog generation, and project releases for Python projects based on Git commit messages. It integrates with various CI/CD pipelines and supports multiple version control systems and distribution platforms. The current version is 10.5.3, with releases typically following breaking changes or significant feature additions.
Warnings
- breaking Configuration was fully moved from legacy files like `release.config.json` or `setup.cfg` to `pyproject.toml`. Older configuration files are no longer parsed.
- breaking Python 3.7 support has been officially dropped. The library now requires Python 3.8 or newer.
- breaking The configuration option `commit_parser` was renamed to `commit_analyzer` in `pyproject.toml`.
- gotcha Shallow Git clones in CI/CD pipelines (e.g., `fetch-depth: 1` in GitHub Actions checkout) can prevent `semantic-release` from accessing full commit history or older tags, leading to incorrect version calculations or failures.
- gotcha Incorrectly configured `version_source` or `version_variable` paths can cause `semantic-release` to fail finding or updating the project's version string.
Install
-
pip install python-semantic-release -
pip install 'python-semantic-release[git]' -
pip install 'python-semantic-release[github]' -
pip install 'python-semantic-release[gitlab]'
Imports
- semantic_release.cli.main
from semantic_release.cli import main
Quickstart
import subprocess
import os
import shutil
def run_semantic_release_demo():
# Setup a temporary directory for the demo
demo_dir = "semantic_release_demo"
if os.path.exists(demo_dir):
shutil.rmtree(demo_dir)
os.makedirs(demo_dir)
os.chdir(demo_dir)
try:
# 1. Initialize a Git repository
subprocess.run(['git', 'init', '-b', 'main'], check=True, capture_output=True)
subprocess.run(['git', 'config', 'user.email', 'test@example.com'], check=True, capture_output=True)
subprocess.run(['git', 'config', 'user.name', 'Test User'], check=True, capture_output=True)
# 2. Create a minimal pyproject.toml for configuration
pyproject_content = '''
[tool.semantic_release]
branch = "main"
version_source = "tag"
changelog_file = "CHANGELOG.md"
'''
with open("pyproject.toml", "w") as f:
f.write(pyproject_content)
# 3. Add some initial content and commit
with open('README.md', 'w') as f:
f.write('# My Project\n\nThis is a demo project.')
subprocess.run(['git', 'add', 'README.md', 'pyproject.toml'], check=True, capture_output=True)
subprocess.run(['git', 'commit', '-m', 'feat: Initial commit and project setup'], check=True, capture_output=True)
print("Successfully set up demo Git repository and pyproject.toml.\n")
# 4. Run semantic-release in dry-run mode
print("--- Running semantic-release publish (dry run) ---")
result = subprocess.run(
['semantic-release', 'publish', '--dry-run'],
capture_output=True,
text=True,
check=True
)
print("STDOUT:\n", result.stdout)
print("STDERR:\n", result.stderr)
print("\nSemantic Release Dry Run completed successfully! Above is the simulated output.")
print("\nTo perform a real release, remove '--dry-run' and ensure a remote Git repository is configured.")
except subprocess.CalledProcessError as e:
print(f"Error during semantic-release demo: {e}")
print("STDOUT:\n", e.stdout)
print("STDERR:\n", e.stderr)
finally:
os.chdir('..')
shutil.rmtree(demo_dir, ignore_errors=True)
print(f"\nCleaned up temporary directory: {demo_dir}")
if __name__ == '__main__':
run_semantic_release_demo()