Consolidate to single dlp_io module and publish release artifacts via Gitea Actions
publish-dlp-io / publish (push) Successful in 1m27s
publish-dlp-io / publish (push) Successful in 1m27s
This commit is contained in:
@@ -11,6 +11,7 @@ from enum import Enum
|
||||
from pathlib import Path, PurePosixPath
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
from packaging.specifiers import SpecifierSet
|
||||
from packaging.utils import canonicalize_name, parse_wheel_filename
|
||||
from packaging.version import Version
|
||||
@@ -19,11 +20,12 @@ import dlp_io
|
||||
|
||||
try:
|
||||
import tomllib
|
||||
except ModuleNotFoundError: # Python 3.9-3.10
|
||||
except ModuleNotFoundError: # Python 3.10
|
||||
import tomli as tomllib
|
||||
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
||||
WORKFLOW_PATH = PROJECT_ROOT / ".gitea" / "workflows" / "publish-dlp-io.yaml"
|
||||
|
||||
|
||||
class DynamicField(Enum):
|
||||
@@ -38,6 +40,14 @@ class PackageClassifier(Enum):
|
||||
WINDOWS = "Operating System :: Microsoft :: Windows"
|
||||
|
||||
|
||||
class WorkflowStep(Enum):
|
||||
CLONE_TAG = "Clone immutable package tag"
|
||||
TEST_MATRIX = "Test Python 3.10-3.14"
|
||||
BUILD = "Build and check distribution"
|
||||
SMOKE = "Smoke test release artifacts"
|
||||
RELEASE = "Create Gitea release with wheels"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class BuiltDistributions:
|
||||
wheel: Path
|
||||
@@ -49,15 +59,25 @@ def _load_pyproject() -> dict:
|
||||
return tomllib.load(file)
|
||||
|
||||
|
||||
def _load_workflow() -> dict:
|
||||
with WORKFLOW_PATH.open(encoding="utf-8") as file:
|
||||
return yaml.safe_load(file)
|
||||
|
||||
|
||||
def _copy_source_tree(source: Path) -> None:
|
||||
source.mkdir()
|
||||
shutil.copy2(PROJECT_ROOT / "pyproject.toml", source)
|
||||
shutil.copy2(PROJECT_ROOT / "MANIFEST.in", source)
|
||||
shutil.copy2(PROJECT_ROOT / "setup.py", source)
|
||||
shutil.copy2(PROJECT_ROOT / "dlp_io.py", source)
|
||||
shutil.copytree(PROJECT_ROOT / "docs", source / "docs")
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def built_distributions(tmp_path_factory: pytest.TempPathFactory) -> BuiltDistributions:
|
||||
root = tmp_path_factory.mktemp("dlp-io-build")
|
||||
source = root / "source"
|
||||
source.mkdir()
|
||||
shutil.copy2(PROJECT_ROOT / "pyproject.toml", source)
|
||||
shutil.copy2(PROJECT_ROOT / "MANIFEST.in", source)
|
||||
shutil.copytree(PROJECT_ROOT / "dlp_io", source / "dlp_io")
|
||||
shutil.copytree(PROJECT_ROOT / "docs", source / "docs")
|
||||
_copy_source_tree(source)
|
||||
|
||||
dist = root / "dist"
|
||||
completed = subprocess.run(
|
||||
@@ -85,10 +105,9 @@ def built_distributions(tmp_path_factory: pytest.TempPathFactory) -> BuiltDistri
|
||||
def test_pyproject_declares_structured_public_package_contract() -> None:
|
||||
config = _load_pyproject()
|
||||
project = config["project"]
|
||||
setuptools = config["tool"]["setuptools"]
|
||||
|
||||
assert PackageName(canonicalize_name(project["name"])) is PackageName.DLP_IO
|
||||
assert SpecifierSet(project["requires-python"]) == SpecifierSet(">=3.9")
|
||||
assert SpecifierSet(project["requires-python"]) == SpecifierSet(">=3.10")
|
||||
assert {DynamicField(item) for item in project["dynamic"]} == {
|
||||
DynamicField.VERSION
|
||||
}
|
||||
@@ -99,10 +118,6 @@ def test_pyproject_declares_structured_public_package_contract() -> None:
|
||||
if item in known_classifier_values
|
||||
}
|
||||
assert PackageClassifier.WINDOWS in known_classifiers
|
||||
assert {Path(item) for item in setuptools["packages"]} == {Path("dlp_io")}
|
||||
assert {Path(item) for item in setuptools["package-data"]["dlp_io"]} == {
|
||||
Path("py.typed")
|
||||
}
|
||||
|
||||
version_ref = config["tool"]["setuptools"]["dynamic"]["version"]["attr"]
|
||||
module_name, attribute_name = version_ref.rsplit(".", 1)
|
||||
@@ -121,8 +136,8 @@ def test_wheel_contains_only_installable_dlp_io_runtime(
|
||||
assert version == Version(dlp_io.__version__)
|
||||
assert build == ()
|
||||
assert tags
|
||||
assert PurePosixPath("dlp_io/__init__.py") in members
|
||||
assert PurePosixPath("dlp_io/py.typed") in members
|
||||
assert PurePosixPath("dlp_io.py") in members
|
||||
assert not [item for item in members if item.suffix == ".pyd"]
|
||||
member_roots = {Path(item.parts[0]) for item in members}
|
||||
assert member_roots.isdisjoint({Path("tests"), Path("Lib")})
|
||||
assert PurePosixPath(".env") not in members
|
||||
@@ -139,9 +154,23 @@ def test_sdist_contains_package_sources_and_public_readme_only(
|
||||
}
|
||||
|
||||
assert PurePosixPath("pyproject.toml") in members
|
||||
assert PurePosixPath("setup.py") in members
|
||||
assert PurePosixPath("docs/DLP_IO_LIBRARY.md") in members
|
||||
assert PurePosixPath("dlp_io/__init__.py") in members
|
||||
assert PurePosixPath("dlp_io.py") in members
|
||||
member_roots = {Path(item.parts[0]) for item in members}
|
||||
assert Path("tests") not in member_roots
|
||||
assert PurePosixPath("README.md") not in members
|
||||
assert PurePosixPath(".env") not in members
|
||||
|
||||
|
||||
def test_publish_workflow_tests_builds_and_releases_tagged_distributions() -> None:
|
||||
document = _load_workflow()
|
||||
trigger = document.get("on", document.get(True))
|
||||
assert set(trigger["push"]["tags"]) == {"dlp-io-v*.*.*"}
|
||||
assert "workflow_dispatch" in trigger
|
||||
|
||||
job = document["jobs"]["publish"]
|
||||
assert job["runs-on"] == "windows-latest"
|
||||
assert Path(job["defaults"]["run"]["working-directory"]) == Path("repo")
|
||||
step_names = [step["name"] for step in job["steps"]]
|
||||
assert step_names == [step.value for step in WorkflowStep]
|
||||
|
||||
Reference in New Issue
Block a user