add: Versionierung

- semantic versioning
- auto update on build
- git hash zusätzlich
- Anzeige per cli und im Fenster
This commit is contained in:
Rob committed 2026-05-08 08:35:50 +02:00
1 parent 250a473253
commit 102b485794
6 files changed
+131 -6

No files matched your search

+10 -2
View File
@@ -14,7 +14,7 @@ echo.
echo === AnwesenheitPDF Build === echo === AnwesenheitPDF Build ===
echo. echo.
echo [1/2] Abhaengigkeiten installieren... echo [1/3] Abhaengigkeiten installieren...
pip install -r requirements.txt --quiet && pip install -r requirements-dev.txt --quiet pip install -r requirements.txt --quiet && pip install -r requirements-dev.txt --quiet
if %ERRORLEVEL% neq 0 ( if %ERRORLEVEL% neq 0 (
echo [FEHLER] pip install fehlgeschlagen. echo [FEHLER] pip install fehlgeschlagen.
@@ -22,7 +22,15 @@ if %ERRORLEVEL% neq 0 (
exit /b 1 exit /b 1
) )
echo [2/2] Build starten... echo [2/3] Version aktualisieren...
python update_version.py
if %ERRORLEVEL% neq 0 (
echo [FEHLER] Version-Update fehlgeschlagen.
pause
exit /b 1
)
echo [3/3] Build starten...
echo. echo.
python -m PyInstaller ^ python -m PyInstaller ^
+12 -2
View File
@@ -1,4 +1,5 @@
{ {
"version": "1.0.1+250a473",
"antragsnummer": "100740439", "antragsnummer": "100740439",
"ort": "Dresden", "ort": "Dresden",
"template_pdf": "template/sab.pdf", "template_pdf": "template/sab.pdf",
@@ -24,7 +25,16 @@
"Nov": "11", "Nov": "11",
"Dez": "12" "Dez": "12"
}, },
"valid_status_codes": ["K", "KK", "E", "F", "P", "U", "A", "V"], "valid_status_codes": [
"K",
"KK",
"E",
"F",
"P",
"U",
"A",
"V"
],
"plan_hours_value": "6", "plan_hours_value": "6",
"pdf_field_ort": "unterschrift.ort", "pdf_field_ort": "unterschrift.ort",
"pdf_field_erstellungsdatum": "unterschrift.datum", "pdf_field_erstellungsdatum": "unterschrift.datum",
@@ -33,4 +43,4 @@
"pdf_use_display_values": true, "pdf_use_display_values": true,
"pdf_need_appearances": false, "pdf_need_appearances": false,
"excel_network_source": "J:\\Fachbereiche\\BO\\Produktionsschule\\Maßnahmeunterlagen\\30_Teilnehmende\\01_Anwesenheit\\Anwesenheitsliste\\Anwesenheitsliste 2026.xlsx" "excel_network_source": "J:\\Fachbereiche\\BO\\Produktionsschule\\Maßnahmeunterlagen\\30_Teilnehmende\\01_Anwesenheit\\Anwesenheitsliste\\Anwesenheitsliste 2026.xlsx"
} }
+8 -1
View File
@@ -23,8 +23,15 @@ from src.validators import show_preview_and_confirm, validate
@click.group() @click.group()
def cli() -> None: @click.pass_context
def cli(ctx: click.Context) -> None:
"""Anwesenheit PDF Generator — Excel → PDF""" """Anwesenheit PDF Generator — Excel → PDF"""
try:
config = load_config()
version = config.get("version", "unknown")
click.echo(f"Anwesenheit PDF Generator v{version}")
except Exception as exc:
click.echo(f"Fehler beim Laden der Konfiguration: {exc}", err=True)
@cli.command("validate") @cli.command("validate")
+5 -1
View File
@@ -156,7 +156,11 @@ class AnwesenheitApp(ctk.CTk):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
self.title("Anwesenheit PDF Generator") # Load config and version
config = load_config()
version = config.get("version", "unknown")
self.title(f"Anwesenheit PDF Generator v{version}")
self.geometry("720x680") self.geometry("720x680")
self.resizable(False, False) self.resizable(False, False)
+6
View File
@@ -4,6 +4,7 @@
"description": "Konfigurationsschema für config.json", "description": "Konfigurationsschema für config.json",
"type": "object", "type": "object",
"required": [ "required": [
"version",
"antragsnummer", "antragsnummer",
"ort", "ort",
"template_pdf", "template_pdf",
@@ -20,6 +21,11 @@
"pauschale_value" "pauschale_value"
], ],
"properties": { "properties": {
"version": {
"type": "string",
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$",
"description": "Semantic version (z. B. 1.0.0)"
},
"antragsnummer": { "antragsnummer": {
"type": "string", "type": "string",
"description": "SAB-Antragsnummer (statisch, aus config)" "description": "SAB-Antragsnummer (statisch, aus config)"
+90
View File
@@ -0,0 +1,90 @@
"""Update version in config.json with Git commit hash."""
import json
import re
import subprocess
import sys
from pathlib import Path
def get_git_commit_hash() -> str:
"""Get the short Git commit hash. Return 'unknown' if Git not available."""
try:
result = subprocess.run(
["git", "rev-parse", "--short", "HEAD"],
capture_output=True,
text=True,
cwd=Path(__file__).parent,
)
if result.returncode == 0:
return result.stdout.strip()
return "unknown"
except Exception:
return "unknown"
def parse_version(version_str: str) -> tuple[int, int, int]:
"""Parse semantic version and return (major, minor, patch)."""
# Remove any build metadata (e.g., "+abc123")
base_version = version_str.split("+")[0].strip()
match = re.match(r"^(\d+)\.(\d+)\.(\d+)$", base_version)
if not match:
raise ValueError(f"Invalid semantic version format: {base_version}")
return int(match.group(1)), int(match.group(2)), int(match.group(3))
def increment_patch_version(version_str: str) -> str:
"""Increment patch version (e.g., 1.0.0 → 1.0.1)."""
major, minor, patch = parse_version(version_str)
return f"{major}.{minor}.{patch + 1}"
def update_version() -> None:
"""Update config.json version with incremented patch and Git hash."""
config_path = Path(__file__).parent / "config.json"
if not config_path.exists():
print(f"[ERROR] config.json not found at {config_path}")
sys.exit(1)
# Load config
try:
with open(config_path, "r", encoding="utf-8") as f:
config = json.load(f)
except Exception as exc:
print(f"[ERROR] Failed to read config.json: {exc}")
sys.exit(1)
# Get current version
current_version = config.get("version", "1.0.0")
print(f"Current version: {current_version}")
# Increment patch version
new_base_version = increment_patch_version(current_version)
print(f"New version (base): {new_base_version}")
# Get Git commit hash
git_hash = get_git_commit_hash()
print(f"Git commit hash: {git_hash}")
# Combine version with Git hash (Semantic Versioning build metadata)
new_version = f"{new_base_version}+{git_hash}"
print(f"Final version: {new_version}")
# Update config
config["version"] = new_version
# Write back to config.json
try:
with open(config_path, "w", encoding="utf-8") as f:
json.dump(config, f, indent=4, ensure_ascii=False)
print(f"\n✓ Version updated in config.json")
except Exception as exc:
print(f"[ERROR] Failed to write config.json: {exc}")
sys.exit(1)
if __name__ == "__main__":
update_version()