feat: add semantic-release and conventional commit infrastructure
- Create pyproject.toml with python-semantic-release configuration - Add release.yml workflow for automated releases - Add commitlint pre-commit hook for conventional commits validation - Add python-semantic-release to dev dependencies Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
name: Semantic Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Semantic Release
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'christianlouis/DocuElevate'
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install python-semantic-release
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Run Semantic Release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
semantic-release version --print
|
||||
semantic-release version
|
||||
semantic-release publish
|
||||
|
||||
- name: Update VERSION file if changed
|
||||
run: |
|
||||
if [ -f VERSION ]; then
|
||||
git add VERSION
|
||||
if ! git diff --staged --quiet; then
|
||||
git commit -m "chore(release): update VERSION file [skip ci]"
|
||||
git push
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: Trigger Docker Build on Tag
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const ref = context.ref;
|
||||
const tag = ref.replace('refs/tags/', '');
|
||||
console.log(`New tag created: ${tag}`);
|
||||
console.log('Docker build will be triggered automatically by the docker-build workflow');
|
||||
@@ -69,3 +69,11 @@ repos:
|
||||
.+\.json|
|
||||
.env.demo
|
||||
)$
|
||||
|
||||
# Conventional commits validation
|
||||
- repo: https://github.com/compilerla/conventional-pre-commit
|
||||
rev: v3.0.0
|
||||
hooks:
|
||||
- id: conventional-pre-commit
|
||||
stages: [commit-msg]
|
||||
args: []
|
||||
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=45", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "docuelevate"
|
||||
dynamic = ["version"]
|
||||
description = "Intelligent document processing system with AI-powered metadata extraction"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.11"
|
||||
license = {text = "Apache-2.0"}
|
||||
authors = [
|
||||
{name = "Christian Louis", email = "christianlouis@users.noreply.github.com"}
|
||||
]
|
||||
keywords = ["document", "processing", "ocr", "ai", "metadata", "extraction"]
|
||||
classifiers = [
|
||||
"Development Status :: 4 - Beta",
|
||||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/christianlouis/DocuElevate"
|
||||
Documentation = "https://github.com/christianlouis/DocuElevate/tree/main/docs"
|
||||
Repository = "https://github.com/christianlouis/DocuElevate"
|
||||
Issues = "https://github.com/christianlouis/DocuElevate/issues"
|
||||
Changelog = "https://github.com/christianlouis/DocuElevate/blob/main/CHANGELOG.md"
|
||||
|
||||
[tool.setuptools.dynamic]
|
||||
version = {file = "VERSION"}
|
||||
|
||||
[tool.semantic_release]
|
||||
version_toml = []
|
||||
version_variables = ["VERSION:__version__"]
|
||||
version_source = "tag"
|
||||
commit_version_number = true
|
||||
tag_format = "v{version}"
|
||||
major_on_zero = false
|
||||
allow_zero_version = true
|
||||
build_command = """
|
||||
chmod +x scripts/generate_build_metadata.sh
|
||||
./scripts/generate_build_metadata.sh
|
||||
"""
|
||||
|
||||
[tool.semantic_release.branches.main]
|
||||
match = "main"
|
||||
prerelease = false
|
||||
|
||||
[tool.semantic_release.changelog]
|
||||
template_dir = "templates"
|
||||
changelog_file = "CHANGELOG.md"
|
||||
exclude_commit_patterns = [
|
||||
"^chore\\(release\\):",
|
||||
"^Merge",
|
||||
"^Bump version",
|
||||
]
|
||||
|
||||
[tool.semantic_release.changelog.environment]
|
||||
block_start_string = "{%"
|
||||
block_end_string = "%}"
|
||||
variable_start_string = "{{"
|
||||
variable_end_string = "}}"
|
||||
comment_start_string = "{#"
|
||||
comment_end_string = "#}"
|
||||
trim_blocks = false
|
||||
lstrip_blocks = false
|
||||
newline_sequence = "\n"
|
||||
keep_trailing_newline = false
|
||||
extensions = []
|
||||
autoescape = true
|
||||
|
||||
[tool.semantic_release.commit_parser_options]
|
||||
allowed_tags = [
|
||||
"feat",
|
||||
"fix",
|
||||
"docs",
|
||||
"style",
|
||||
"refactor",
|
||||
"perf",
|
||||
"test",
|
||||
"build",
|
||||
"ci",
|
||||
"chore",
|
||||
]
|
||||
minor_tags = ["feat"]
|
||||
patch_tags = ["fix", "perf"]
|
||||
default_bump_level = 0
|
||||
|
||||
[tool.semantic_release.remote]
|
||||
name = "origin"
|
||||
type = "github"
|
||||
ignore_token_for_push = false
|
||||
|
||||
[tool.semantic_release.remote.token]
|
||||
env = "GH_TOKEN"
|
||||
|
||||
[tool.semantic_release.publish]
|
||||
dist_glob_patterns = []
|
||||
upload_to_vcs_release = true
|
||||
upload_to_pypi = false
|
||||
upload_to_repository = false
|
||||
|
||||
# Black configuration
|
||||
[tool.black]
|
||||
line-length = 120
|
||||
target-version = ['py311']
|
||||
include = '\.pyi?$'
|
||||
extend-exclude = '''
|
||||
/(
|
||||
# directories
|
||||
\.eggs
|
||||
| \.git
|
||||
| \.hg
|
||||
| \.mypy_cache
|
||||
| \.tox
|
||||
| \.venv
|
||||
| build
|
||||
| dist
|
||||
| migrations
|
||||
)/
|
||||
'''
|
||||
|
||||
# isort configuration
|
||||
[tool.isort]
|
||||
profile = "black"
|
||||
line_length = 120
|
||||
skip_gitignore = true
|
||||
known_first_party = ["app"]
|
||||
sections = ["FUTURE", "STDLIB", "THIRDPARTY", "FIRSTPARTY", "LOCALFOLDER"]
|
||||
|
||||
# pytest configuration
|
||||
[tool.pytest.ini_options]
|
||||
minversion = "7.0"
|
||||
testpaths = ["tests"]
|
||||
python_files = ["test_*.py"]
|
||||
python_classes = ["Test*"]
|
||||
python_functions = ["test_*"]
|
||||
addopts = [
|
||||
"-v",
|
||||
"--strict-markers",
|
||||
"--strict-config",
|
||||
"--cov=app",
|
||||
"--cov-report=term-missing",
|
||||
"--cov-report=html",
|
||||
"--cov-branch",
|
||||
]
|
||||
markers = [
|
||||
"unit: Unit tests for individual functions/methods",
|
||||
"integration: Integration tests for API endpoints and workflows",
|
||||
"slow: Tests that take significant time to run",
|
||||
"security: Security-related tests",
|
||||
"requires_external: Tests requiring external services (OpenAI, Azure, etc.)",
|
||||
"requires_db: Tests requiring database",
|
||||
"requires_redis: Tests requiring Redis",
|
||||
]
|
||||
|
||||
# mypy configuration
|
||||
[tool.mypy]
|
||||
python_version = "3.11"
|
||||
warn_return_any = true
|
||||
warn_unused_configs = true
|
||||
disallow_untyped_defs = false
|
||||
disallow_incomplete_defs = false
|
||||
check_untyped_defs = true
|
||||
no_implicit_optional = true
|
||||
warn_redundant_casts = true
|
||||
warn_unused_ignores = true
|
||||
warn_no_return = true
|
||||
warn_unreachable = true
|
||||
strict_equality = true
|
||||
ignore_missing_imports = true
|
||||
|
||||
# Coverage configuration
|
||||
[tool.coverage.run]
|
||||
source = ["app"]
|
||||
omit = [
|
||||
"*/tests/*",
|
||||
"*/migrations/*",
|
||||
"*/__pycache__/*",
|
||||
"*/venv/*",
|
||||
"*/env/*",
|
||||
]
|
||||
|
||||
[tool.coverage.report]
|
||||
precision = 2
|
||||
show_missing = true
|
||||
skip_covered = false
|
||||
exclude_lines = [
|
||||
"pragma: no cover",
|
||||
"def __repr__",
|
||||
"raise AssertionError",
|
||||
"raise NotImplementedError",
|
||||
"if __name__ == .__main__.:",
|
||||
"if TYPE_CHECKING:",
|
||||
"@abstractmethod",
|
||||
]
|
||||
@@ -23,4 +23,7 @@ safety>=3.0.0
|
||||
pre-commit>=3.6.0
|
||||
|
||||
# License compliance
|
||||
pip-licenses==5.5.1 # For license compliance checking
|
||||
pip-licenses==5.5.1 # For license compliance checking
|
||||
|
||||
# Release automation
|
||||
python-semantic-release>=9.0.0
|
||||
Reference in New Issue
Block a user