diff --git a/.github/scripts/check_sdist_artifacts.py b/.github/scripts/check_sdist_artifacts.py new file mode 100644 index 0000000..fd24981 --- /dev/null +++ b/.github/scripts/check_sdist_artifacts.py @@ -0,0 +1,35 @@ +"""Check native source distributions after compiled extensions exist.""" + +import shutil +import sys +import tarfile +import tempfile +import tomllib +from pathlib import Path + +from hatchling.builders.sdist import SdistBuilder + +source = Path(sys.argv[1]).resolve() +with tempfile.TemporaryDirectory() as temporary: + project = Path(temporary) / "project" + shutil.copytree( + source, + project, + ignore=shutil.ignore_patterns(".git", ".venv", "__pycache__", "node_modules", "target", "dist", "vcpkg", "vcpkg_installed", "emsdk"), + ) + config = tomllib.loads((project / "pyproject.toml").read_text()) + module = config["tool"]["hatch"]["build"]["targets"]["wheel"]["packages"][0] + extensions = (".so", ".dll", ".dylib", ".pyd") + for suffix in extensions: + (project / module / f"_sdist_binary_check{suffix}").write_bytes(b"prebuilt binary") + + output = Path(temporary) / "dist" + output.mkdir() + filename = next(SdistBuilder(str(project)).build(directory=str(output))) + with tarfile.open(output / filename) as archive: + names = archive.getnames() + + binaries = [name for name in names if name.endswith(extensions)] + assert not binaries, f"Source distribution contains compiled extensions: {binaries}" + assert any(name.endswith((".cpp", ".rs")) for name in names), "Source distribution is missing native sources" + print(f"{source.name}: source distribution excludes compiled extensions and retains native sources") diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 19352ed..96e91e7 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -122,3 +122,9 @@ jobs: - name: Test template run: make test-${{ matrix.template }} + + - name: Check source distribution artifacts + run: python .github/scripts/check_sdist_artifacts.py ../python-template-${{ matrix.template }} + env: + HATCH_BUILD_NO_HOOKS: '1' + if: matrix.template == 'cpp' || matrix.template == 'cppjswasm' || matrix.template == 'rust' || matrix.template == 'rustjswasm' diff --git a/python/cpp/pyproject.toml.jinja b/python/cpp/pyproject.toml.jinja index 89c536b..cdbc0d5 100644 --- a/python/cpp/pyproject.toml.jinja +++ b/python/cpp/pyproject.toml.jinja @@ -121,13 +121,6 @@ exclude_also = [ ignore_errors = true fail_under = 50 -[tool.hatch.build] -artifacts = [ - "{{ module }}/*.dll", - "{{ module }}/*.dylib", - "{{ module }}/*.so", -] - [tool.hatch.build.sources] src = "/" @@ -138,6 +131,7 @@ libraries = [ ] [tool.hatch.build.targets.sdist] +exclude = ["*.dll", "*.dylib", "*.so", "*.pyd"] packages = [ "{{ module }}", "cpp", @@ -149,6 +143,11 @@ packages = [ {% endif %} [tool.hatch.build.targets.wheel] +artifacts = [ + "{{ module }}/*.dll", + "{{ module }}/*.dylib", + "{{ module }}/*.so", +] packages = [ "{{ module }}", ] diff --git a/python/cppjswasm/pyproject.toml.jinja b/python/cppjswasm/pyproject.toml.jinja index 9725f84..1c7ba27 100644 --- a/python/cppjswasm/pyproject.toml.jinja +++ b/python/cppjswasm/pyproject.toml.jinja @@ -135,9 +135,6 @@ fail_under = 50 [tool.hatch.build] artifacts = [ - "{{ module }}/*.dll", - "{{ module }}/*.dylib", - "{{ module }}/*.so", "{{ module }}/extension", ] @@ -159,6 +156,7 @@ libraries = [ ] [tool.hatch.build.targets.sdist] +exclude = ["*.dll", "*.dylib", "*.so", "*.pyd"] packages = [ "{{ module }}", "cpp", @@ -171,6 +169,12 @@ packages = [ {% endif %} [tool.hatch.build.targets.wheel] +artifacts = [ + "{{ module }}/*.dll", + "{{ module }}/*.dylib", + "{{ module }}/*.so", + "{{ module }}/extension", +] packages = [ "{{ module }}", ] diff --git a/python/rust/pyproject.toml.jinja b/python/rust/pyproject.toml.jinja index 2d86769..39f4594 100644 --- a/python/rust/pyproject.toml.jinja +++ b/python/rust/pyproject.toml.jinja @@ -141,13 +141,6 @@ exclude_also = [ ignore_errors = true fail_under = 50 -[tool.hatch.build] -artifacts = [ - "{{ module }}/*.dll", - "{{ module }}/*.dylib", - "{{ module }}/*.so", -] - [tool.hatch.build.sources] src = "/" @@ -165,11 +158,20 @@ packages = [ "Cargo.lock", ] exclude = [ + "*.dll", + "*.dylib", + "*.so", + "*.pyd", "rust/Makefile", "target", ] [tool.hatch.build.targets.wheel] +artifacts = [ + "{{ module }}/*.dll", + "{{ module }}/*.dylib", + "{{ module }}/*.so", +] packages = [ "{{ module }}", ] diff --git a/python/rustjswasm/pyproject.toml.jinja b/python/rustjswasm/pyproject.toml.jinja index 783cacb..0c802eb 100644 --- a/python/rustjswasm/pyproject.toml.jinja +++ b/python/rustjswasm/pyproject.toml.jinja @@ -156,9 +156,6 @@ fail_under = 50 [tool.hatch.build] artifacts = [ - "{{ module }}/*.dll", - "{{ module }}/*.dylib", - "{{ module }}/*.so", "{{ module }}/extension", ] @@ -188,9 +185,10 @@ packages = [ "Cargo.lock", ] exclude = [ - "{{ module }}/*.dll", - "{{ module }}/*.dylib", - "{{ module }}/*.so", + "*.dll", + "*.dylib", + "*.so", + "*.pyd", "{{ module }}/extension", "js/dist", "js/node_modules", @@ -199,6 +197,12 @@ exclude = [ ] [tool.hatch.build.targets.wheel] +artifacts = [ + "{{ module }}/*.dll", + "{{ module }}/*.dylib", + "{{ module }}/*.so", + "{{ module }}/extension", +] packages = [ "{{ module }}", ]