From 84ebf123ac4818e71b2ee6dac03160ed1ad9b89f Mon Sep 17 00:00:00 2001 From: Anto Subash Date: Wed, 22 Apr 2026 14:22:19 +0200 Subject: [PATCH] fix(packaging): resolve license-file path so sdists pass twine check PEP 639 forbids parent-directory indicators in license-files. Twine rejected every sdist with `InvalidDistribution: '../../LICENSE' is invalid for 'license-file'`, blocking the release workflow. Replace the `../../LICENSE` path with a plain `LICENSE` entry in each package's pyproject.toml, and add a `LICENSE` symlink in each package directory pointing at the repo-root LICENSE so the file resolves at build time without duplicating its contents. Verified: all 14 wheels and 14 sdists built via `uv build --all-packages` now pass `twine check`. --- framework/core/LICENSE | 1 + framework/core/pyproject.toml | 2 +- framework/db/LICENSE | 1 + framework/db/pyproject.toml | 2 +- framework/hosting/LICENSE | 1 + framework/hosting/pyproject.toml | 2 +- framework/testing/LICENSE | 1 + framework/testing/pyproject.toml | 2 +- modules/auth/LICENSE | 1 + modules/auth/pyproject.toml | 2 +- modules/background_tasks/LICENSE | 1 + modules/background_tasks/pyproject.toml | 2 +- modules/dashboard/LICENSE | 1 + modules/dashboard/pyproject.toml | 2 +- modules/datasets/LICENSE | 1 + modules/datasets/pyproject.toml | 2 +- modules/feature_flags/LICENSE | 1 + modules/feature_flags/pyproject.toml | 2 +- modules/file_storage/LICENSE | 1 + modules/file_storage/pyproject.toml | 2 +- modules/permissions/LICENSE | 1 + modules/permissions/pyproject.toml | 2 +- modules/products/LICENSE | 1 + modules/products/pyproject.toml | 2 +- modules/settings/LICENSE | 1 + modules/settings/pyproject.toml | 2 +- modules/users/LICENSE | 1 + modules/users/pyproject.toml | 2 +- 28 files changed, 28 insertions(+), 14 deletions(-) create mode 120000 framework/core/LICENSE create mode 120000 framework/db/LICENSE create mode 120000 framework/hosting/LICENSE create mode 120000 framework/testing/LICENSE create mode 120000 modules/auth/LICENSE create mode 120000 modules/background_tasks/LICENSE create mode 120000 modules/dashboard/LICENSE create mode 120000 modules/datasets/LICENSE create mode 120000 modules/feature_flags/LICENSE create mode 120000 modules/file_storage/LICENSE create mode 120000 modules/permissions/LICENSE create mode 120000 modules/products/LICENSE create mode 120000 modules/settings/LICENSE create mode 120000 modules/users/LICENSE diff --git a/framework/core/LICENSE b/framework/core/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/framework/core/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/framework/core/pyproject.toml b/framework/core/pyproject.toml index a3d800c4..7995a75b 100644 --- a/framework/core/pyproject.toml +++ b/framework/core/pyproject.toml @@ -4,7 +4,7 @@ version = "0.0.1" description = "Module-system primitives for the simple_module framework — ModuleBase, discovery, diagnostics, events" readme = "README.md" license = "MIT" -license-files = ["../../LICENSE"] +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "Anto Subash", email = "antosubash@live.com" }] keywords = ["simple-module", "fastapi", "modular-monolith", "plugin-system", "module-discovery"] diff --git a/framework/db/LICENSE b/framework/db/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/framework/db/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/framework/db/pyproject.toml b/framework/db/pyproject.toml index 2ccddf00..2641f3d4 100644 --- a/framework/db/pyproject.toml +++ b/framework/db/pyproject.toml @@ -4,7 +4,7 @@ version = "0.0.1" description = "Per-module SQLModel Base, async session, standard mixins (Audit, SoftDelete, MultiTenant, Versioned) for simple_module" readme = "README.md" license = "MIT" -license-files = ["../../LICENSE"] +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "Anto Subash", email = "antosubash@live.com" }] keywords = ["simple-module", "sqlmodel", "sqlalchemy", "async", "alembic", "multi-tenant"] diff --git a/framework/hosting/LICENSE b/framework/hosting/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/framework/hosting/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/framework/hosting/pyproject.toml b/framework/hosting/pyproject.toml index 331abb96..38be3525 100644 --- a/framework/hosting/pyproject.toml +++ b/framework/hosting/pyproject.toml @@ -4,7 +4,7 @@ version = "0.0.1" description = "FastAPI + Inertia.js host runtime for simple_module — app_builder, middleware stack, CLI (sm / simple-module), scaffolding" readme = "README.md" license = "MIT" -license-files = ["../../LICENSE"] +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "Anto Subash", email = "antosubash@live.com" }] keywords = ["simple-module", "fastapi", "inertia", "starlette", "uvicorn", "scaffolding"] diff --git a/framework/testing/LICENSE b/framework/testing/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/framework/testing/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/framework/testing/pyproject.toml b/framework/testing/pyproject.toml index e66ce090..69d18f2e 100644 --- a/framework/testing/pyproject.toml +++ b/framework/testing/pyproject.toml @@ -4,7 +4,7 @@ version = "0.0.1" description = "Shared pytest fixtures (app, client, db_session, authenticated_client) for writing simple_module module tests" readme = "README.md" license = "MIT" -license-files = ["../../LICENSE"] +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "Anto Subash", email = "antosubash@live.com" }] keywords = ["simple-module", "pytest", "pytest-plugin", "fixtures", "testing"] diff --git a/modules/auth/LICENSE b/modules/auth/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/modules/auth/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/modules/auth/pyproject.toml b/modules/auth/pyproject.toml index e1c4f59e..e785b230 100644 --- a/modules/auth/pyproject.toml +++ b/modules/auth/pyproject.toml @@ -4,7 +4,7 @@ version = "0.0.1" description = "Session-cookie authentication primitives — middleware, login/logout, redirect helpers for simple_module" readme = "README.md" license = "MIT" -license-files = ["../../LICENSE"] +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "Anto Subash", email = "antosubash@live.com" }] keywords = ["simple-module", "fastapi", "authentication", "session", "cookie"] diff --git a/modules/background_tasks/LICENSE b/modules/background_tasks/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/modules/background_tasks/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/modules/background_tasks/pyproject.toml b/modules/background_tasks/pyproject.toml index 2ce62d57..ddf8c1bb 100644 --- a/modules/background_tasks/pyproject.toml +++ b/modules/background_tasks/pyproject.toml @@ -4,7 +4,7 @@ version = "0.0.1" description = "Celery + Redis task queue with admin UI for monitoring and retrying failed/stuck tasks" readme = "README.md" license = "MIT" -license-files = ["../../LICENSE"] +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "Anto Subash", email = "antosubash@live.com" }] keywords = ["simple-module", "celery", "redis", "task-queue", "background-jobs"] diff --git a/modules/dashboard/LICENSE b/modules/dashboard/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/modules/dashboard/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/modules/dashboard/pyproject.toml b/modules/dashboard/pyproject.toml index ab466483..460debe1 100644 --- a/modules/dashboard/pyproject.toml +++ b/modules/dashboard/pyproject.toml @@ -4,7 +4,7 @@ version = "0.0.1" description = "Admin landing page and sidebar menu host for authenticated users of a simple_module app" readme = "README.md" license = "MIT" -license-files = ["../../LICENSE"] +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "Anto Subash", email = "antosubash@live.com" }] keywords = ["simple-module", "dashboard", "admin", "inertia"] diff --git a/modules/datasets/LICENSE b/modules/datasets/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/modules/datasets/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/modules/datasets/pyproject.toml b/modules/datasets/pyproject.toml index 4fc35af5..933ee342 100644 --- a/modules/datasets/pyproject.toml +++ b/modules/datasets/pyproject.toml @@ -4,7 +4,7 @@ version = "0.0.1" description = "Geospatial + tabular dataset upload, parsing (shapely) and slugging for simple_module apps" readme = "README.md" license = "MIT" -license-files = ["../../LICENSE"] +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "Anto Subash", email = "antosubash@live.com" }] keywords = ["simple-module", "geospatial", "shapely", "datasets", "gis"] diff --git a/modules/feature_flags/LICENSE b/modules/feature_flags/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/modules/feature_flags/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/modules/feature_flags/pyproject.toml b/modules/feature_flags/pyproject.toml index 7abaaabd..2d31e011 100644 --- a/modules/feature_flags/pyproject.toml +++ b/modules/feature_flags/pyproject.toml @@ -4,7 +4,7 @@ version = "0.0.1" description = "Simple feature-flag module with per-tenant overrides and a consumer API for simple_module" readme = "README.md" license = "MIT" -license-files = ["../../LICENSE"] +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "Anto Subash", email = "antosubash@live.com" }] keywords = ["simple-module", "feature-flags", "toggles", "multi-tenant"] diff --git a/modules/file_storage/LICENSE b/modules/file_storage/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/modules/file_storage/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/modules/file_storage/pyproject.toml b/modules/file_storage/pyproject.toml index 0f8b3df5..7217c6cd 100644 --- a/modules/file_storage/pyproject.toml +++ b/modules/file_storage/pyproject.toml @@ -4,7 +4,7 @@ version = "0.0.1" description = "Pluggable file upload + storage (local or S3 via extras) module for simple_module apps" readme = "README.md" license = "MIT" -license-files = ["../../LICENSE"] +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "Anto Subash", email = "antosubash@live.com" }] keywords = ["simple-module", "file-upload", "s3", "storage"] diff --git a/modules/permissions/LICENSE b/modules/permissions/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/modules/permissions/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/modules/permissions/pyproject.toml b/modules/permissions/pyproject.toml index d7b2174a..6ff9dddf 100644 --- a/modules/permissions/pyproject.toml +++ b/modules/permissions/pyproject.toml @@ -4,7 +4,7 @@ version = "0.0.1" description = "RBAC primitives — roles, permissions, @require_permission decorator, admin UI for simple_module" readme = "README.md" license = "MIT" -license-files = ["../../LICENSE"] +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "Anto Subash", email = "antosubash@live.com" }] keywords = ["simple-module", "rbac", "permissions", "authorization"] diff --git a/modules/products/LICENSE b/modules/products/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/modules/products/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/modules/products/pyproject.toml b/modules/products/pyproject.toml index f7e15ece..430d3e58 100644 --- a/modules/products/pyproject.toml +++ b/modules/products/pyproject.toml @@ -4,7 +4,7 @@ version = "0.0.1" description = "Example CRUD module used as a reference / demo for building simple_module modules" readme = "README.md" license = "MIT" -license-files = ["../../LICENSE"] +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "Anto Subash", email = "antosubash@live.com" }] keywords = ["simple-module", "example", "crud", "demo"] diff --git a/modules/settings/LICENSE b/modules/settings/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/modules/settings/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/modules/settings/pyproject.toml b/modules/settings/pyproject.toml index b3ab20e7..c9ad9c80 100644 --- a/modules/settings/pyproject.toml +++ b/modules/settings/pyproject.toml @@ -4,7 +4,7 @@ version = "0.0.1" description = "Runtime settings UI — modules plug their own settings panels into a shared admin view" readme = "README.md" license = "MIT" -license-files = ["../../LICENSE"] +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "Anto Subash", email = "antosubash@live.com" }] keywords = ["simple-module", "settings", "admin", "configuration"] diff --git a/modules/users/LICENSE b/modules/users/LICENSE new file mode 120000 index 00000000..30cff740 --- /dev/null +++ b/modules/users/LICENSE @@ -0,0 +1 @@ +../../LICENSE \ No newline at end of file diff --git a/modules/users/pyproject.toml b/modules/users/pyproject.toml index 47b65199..5d13b986 100644 --- a/modules/users/pyproject.toml +++ b/modules/users/pyproject.toml @@ -4,7 +4,7 @@ version = "0.0.1" description = "Email + password user management, admin invites, RBAC-ready — replaces Keycloak for simple_module apps" readme = "README.md" license = "MIT" -license-files = ["../../LICENSE"] +license-files = ["LICENSE"] requires-python = ">=3.12" authors = [{ name = "Anto Subash", email = "antosubash@live.com" }] keywords = ["simple-module", "users", "authentication", "fastapi-users", "admin"]