diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a5abb77..8ee7cd8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,6 +33,7 @@ jobs: - "3.10" - "3.11" - "3.12" + - "3.13" steps: - name: Checkout uses: actions/checkout@v4 diff --git a/CHANGELOG.md b/CHANGELOG.md index e5dcfd9..f7fda26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.1.0/). ## [Unreleased] +### Behoben / Fixed (2026-11-01) +- **PEP 639 Metadaten-Standardisierung & CI-Matrix-Härtung (Pfad A Repository-Hygiene):** + - **PEP 639 Lizenz-Spezifikation (`pyproject.toml`):** `license = { text = "MIT" }` auf standardkonformen SPDX-String `license = "MIT"` migriert; veralteten Classifier `"License :: OSI Approved :: MIT License"` aus `classifiers` entfernt, um strikte Build-Validierungsfehler (`ValueError: invalid pyproject.toml config: project.license`) in modernen Setuptools-Versionen (>=82.0) fail-closed zu beheben. + - **CI-Matrix-Härtung (`.github/workflows/tests.yml`):** Test-Matrix um Python 3.13 (`"3.13"`) erweitert zur Sicherung der Vorwärtskompatibilität über die gesamte Python 3.10–3.13 Matrix unter Ubuntu-Runnern. + - **Automatisierte Vertragstest-Erweiterung (`tests/test_metadata.py`):** Neuer hermetischer Vertragstest `test_pep_639_license_specification` verankert die PEP-639-Konformität und das Classifier-Verbot; `test_ci_workflow_integrity` um Python 3.13 Matrix-Prüfung ergänzt. + ### Behoben / Fixed (2026-10-31) - **Windows-atomare Dateisystem-Resilienz & Translation CLI CWD-Unabhängigkeit (Software-Bugsearch / Bugsweep):** - **Windows ReadOnly-Overwrite & WinError 5/32 Resilienz (`prosync_utils.py`):** `atomic_write_text` und `atomic_write_json` heben unter Windows vorübergehend den Schreibschutz auf (`stat.S_IWRITE`), wenn die Zieldatei schreibgeschützt existiert, wodurch `PermissionError: [WinError 5] Zugriff verweigert` beim atomaren `os.replace` verhindert wird (inkl. Wiederherstellung des ursprünglichen Dateimodus im Fehlerfall). diff --git a/pyproject.toml b/pyproject.toml index 4436a67..8698521 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ version = "3.2.0" description = "Intelligent local backup synchronization desktop app with automated SQLite WAL database protection" readme = "README.md" requires-python = ">=3.10" -license = { text = "MIT" } +license = "MIT" license-files = ["LICENSE", "NOTICE", "CONTRIBUTING.md", "THIRD_PARTY_LICENSES.md", "THIRD_PARTY_LICENSES.txt"] authors = [ { name = "file-bricks Team", email = "support@lukasgeiger.com" } @@ -39,7 +39,6 @@ classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Win32 (MS Windows)", "Intended Audience :: End Users/Desktop", - "License :: OSI Approved :: MIT License", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX :: Linux", "Operating System :: MacOS", diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 245ca97..effd612 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -119,6 +119,18 @@ def test_pyproject_pep621_metadata() -> None: assert "norecursedirs =" in content, "norecursedirs missing in pyproject.toml" +def test_pep_639_license_specification() -> None: + """Verify pyproject.toml defines license as a valid PEP 639 SPDX string without deprecated license classifiers.""" + pyproject_file = ROOT / "pyproject.toml" + assert pyproject_file.is_file(), "pyproject.toml must exist" + content = pyproject_file.read_text(encoding="utf-8") + + assert 'license = "MIT"' in content, "pyproject.toml must declare license as SPDX string 'license = \"MIT\"'" + assert "License :: OSI Approved ::" not in content, ( + "pyproject.toml must not include 'License :: OSI Approved :: ...' in classifiers when PEP 639 SPDX string license is used" + ) + + def test_ci_workflow_integrity() -> None: """Verify GitHub Actions CI workflows exist and have test coverage.""" workflow_dir = ROOT / ".github" / "workflows" @@ -128,6 +140,7 @@ def test_ci_workflow_integrity() -> None: tests_yml = (workflow_dir / "tests.yml").read_text(encoding="utf-8") assert "python run_tests.py" in tests_yml assert "python -m pytest -ra -v" in tests_yml + assert '"3.13"' in tests_yml, "Python 3.13 matrix entry missing in tests.yml" def test_ci_concurrency_and_timeout_guardrails() -> None: