diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d5ca344..6d36abb 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -32,7 +32,7 @@ jobs: - name: Install build dependencies run: | python -m pip install --upgrade pip - python -m pip install build "twine>=7,<8" ".[dev]" + python -m pip install build "twine>=7,<8" -e ".[dev]" - name: Test release candidate run: python -m pytest -q diff --git a/docs/validation/publisher-admission-031-20261002/COMMANDS.rst b/docs/validation/publisher-admission-031-20261002/COMMANDS.rst new file mode 100644 index 0000000..fcf8a46 --- /dev/null +++ b/docs/validation/publisher-admission-031-20261002/COMMANDS.rst @@ -0,0 +1,38 @@ +Focused qualification command +============================= + +Run from the isolated PolyStore worktree:: + + systemd-run --user --scope --quiet \ + -p MemoryMax=512M -p MemorySwapMax=0 -p CPUQuota=100% \ + timeout 60s taskset -c 0 env \ + PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 PYTHONDONTWRITEBYTECODE=1 \ + OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 MKL_NUM_THREADS=1 \ + PYTHONPATH=/home/ts/wt/polystore-publisher-admission-031-20261002/src \ + /home/ts/wt/openhcs-generated-inputs-installed-parent-20261001/.venv/bin/python -B \ + /home/ts/wt/openhcs-prior-measurement-role-projection-20261001/docs/validation/selected_plane_stream_materialization_20261001/run_bounded_source.py \ + /home/ts/wt/openhcs-generated-inputs-installed-parent-20261001/.venv/bin/python -B -m pytest \ + -o addopts= \ + --basetemp=docs/validation/publisher-admission-031-20261002/qualified-test-temp \ + --junitxml=docs/validation/publisher-admission-031-20261002/qualified.xml \ + tests/test_publisher_admission.py tests/test_basic.py \ + tests/test_imagej_cache_environment.py tests/test_metadata_namespace.py \ + tests/test_roi_region_properties.py tests/test_roi.py \ + tests/test_lazy_package_exports.py -q + +The default coverage/report addopts are disabled for this focused resource-bound +source run, not for the publisher. All selected tests/assertions are unchanged. +Source fixtures prohibit actual Fiji downloads/JVM execution. + +Offline lock attempt (terminal failure):: + + systemd-run --user --scope --quiet \ + -p MemoryMax=512M -p MemorySwapMax=0 -p CPUQuota=100% \ + timeout 60s taskset -c 0 uv lock --offline --no-python-downloads + +No solution for python_full_version >=3.14 / win32: imglyb not found in cache; +polystore[all] requires imglyb==2.1.0. No lock file was changed. + +Owned disposable output is confined to the three source-test-temp, +admission-test-temp and qualified-test-temp directories below this receipt root. +Original log, test XML and qualification notes are durable evidence, not caches. diff --git a/docs/validation/publisher-admission-031-20261002/RECEIPT.rst b/docs/validation/publisher-admission-031-20261002/RECEIPT.rst new file mode 100644 index 0000000..b581a23 --- /dev/null +++ b/docs/validation/publisher-admission-031-20261002/RECEIPT.rst @@ -0,0 +1,73 @@ +PolyStore 0.3.1 publisher admission +================================ + +Source base: 84f322e46871de5ed47e7fd20976ad03e533c1c4 (remote main). +Owner: Dewey, isolated polystore-publisher-admission-031-20261002 worktree. +Parent owns integration, the sole new 0.3.1 tag, and hosted release acceptance. +The immutable failed v0.3.0 tag is untouched. + +Original failure +---------------- + +Run https://github.com/OpenHCSDev/PolyStore/actions/runs/36959840684, +job 110690882405: 9 failed, 545 passed, 19 skipped in 15.91s. +Three failures require child processes to import checkout source; the publisher +installed a regular distribution. Six ROI topology/archive cases fail because +the existing dev extra omitted roifile. No original test or skip is changed. + +The full job log was fetched through the GitHub SDK job-log tool and archived +as original-job-110690882405.log.gz (lossless gzip), preserving UTF-8 text including +its original BOM and final newline: 142020 bytes, SHA256 +542d75ef00bcd8677526131a1afe195cea6fa63edca7eca5aa8e0b1b4e4b703c. + +Ownership and repair +-------------------- + +Replace the existing publisher install with editable .[dev] admission, matching +the existing ordinary test workflow. The later package build and immutable +declaration/publish steps are unchanged. Declare roifile in the original dev +extra, not a workflow-only dependency roster or mandatory runtime requirement. +Advance the sole project version declaration to 0.3.1; the existing package +version and release scripts derive it from distribution/project metadata. + +Current NRA/refactor-audit skills and packaged pattern catalog were read. +MEMB-1/MEMB-2: dependency membership remains in the original extras declaration. +TIME-8: no duplicated version or metadata authority. No Python runtime mechanism +is introduced, so inheritance/MI would be ornamental here. Independent future +dev dependencies need only their own extra entry, not publisher consumer edits. +The real editable-build test reads emitted metadata and the actual source .pth +from the existing setuptools backend rather than mirroring its implementation. + +Open-PR check found only Dependabot PR10, whose publisher-file changes are action +pins; this patch leaves those pins unchanged. Parent's release worktree is not +edited. No environment installation, external download, Fiji/native launch, +science job, tag or release operation was performed. + +Focused source qualification +---------------------------- + +68 PASS, zero skips: publisher admission/editable metadata, basic package, +ImageJ cache policy and fresh-process source, namespace handoff, ROI geometry +and archive roundtrip, and lazy package exports. These include all nine original +failed cases. The initial original-only run was 63 PASS; new admission controls +were 2 PASS. Final combined run: 8.43s pytest, 9.089s monitored wall, +322700 KiB aggregate RSS (315.14 MiB), one CPU, 512 MiB / 60s limits. +See qualified.xml and qualified-source.txt. The command is in COMMANDS.rst. + +Source is explicitly this worktree's src; dependencies/interpreter are readonly +openhcs-generated-inputs-installed-parent-20261001/.venv/bin/python. +The two publisher controls exercise the real offline editable build without +installing its artifact. They verify checkout binding, unfiltered publisher +pytest invocation, derived version, and dev-only ROI dependency metadata. +No installed editable-candidate or hosted 0.3.1 acceptance is claimed. + +Lock limitation +--------------- + +uv lock --offline --no-python-downloads failed because imglyb==2.1.0 is absent +from the cache for the all/bioformats extras. Original uv.lock already records +PolyStore 0.2.18 and ZMQRuntime 0.2.21, inconsistent with base declarations. +The lock is unchanged: no fabricated entries, constrained platforms, dependency +weakening or downloads. Publisher pip does not consume uv.lock. The existing +separate distribution CI lock-check remains unqualified until authorized lock +regeneration; this is not represented as publisher or runtime acceptance. diff --git a/docs/validation/publisher-admission-031-20261002/admission.xml b/docs/validation/publisher-admission-031-20261002/admission.xml new file mode 100644 index 0000000..b39cf3a --- /dev/null +++ b/docs/validation/publisher-admission-031-20261002/admission.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/validation/publisher-admission-031-20261002/focused-originals.xml b/docs/validation/publisher-admission-031-20261002/focused-originals.xml new file mode 100644 index 0000000..3285ae2 --- /dev/null +++ b/docs/validation/publisher-admission-031-20261002/focused-originals.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/validation/publisher-admission-031-20261002/original-job-110690882405.log.gz b/docs/validation/publisher-admission-031-20261002/original-job-110690882405.log.gz new file mode 100644 index 0000000..f379115 Binary files /dev/null and b/docs/validation/publisher-admission-031-20261002/original-job-110690882405.log.gz differ diff --git a/docs/validation/publisher-admission-031-20261002/qualified-source.txt b/docs/validation/publisher-admission-031-20261002/qualified-source.txt new file mode 100644 index 0000000..3abecb3 --- /dev/null +++ b/docs/validation/publisher-admission-031-20261002/qualified-source.txt @@ -0,0 +1,4 @@ +.................................................................... [100%] +- generated xml file: /home/ts/wt/polystore-publisher-admission-031-20261002/docs/validation/publisher-admission-031-20261002/qualified.xml - +68 passed in 8.43s +BOUNDED_SOURCE peak_aggregate_rss_kib=322700 elapsed_seconds=9.089 returncode=0 reason=None diff --git a/docs/validation/publisher-admission-031-20261002/qualified.xml b/docs/validation/publisher-admission-031-20261002/qualified.xml new file mode 100644 index 0000000..b17c68b --- /dev/null +++ b/docs/validation/publisher-admission-031-20261002/qualified.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 40692cb..2bc2ee6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "polystore" -version = "0.3.0" +version = "0.3.1" description = "Framework-agnostic multi-backend storage abstraction for ML and scientific computing" readme = "README.md" requires-python = ">=3.11" @@ -101,6 +101,7 @@ dev = [ "genbadge[coverage]", "pandas>=2.3.1", "jpype1>=1.4.0", + "roifile", "black>=23.0.0", "ruff>=0.1.0", ] diff --git a/tests/test_publisher_admission.py b/tests/test_publisher_admission.py new file mode 100644 index 0000000..fcec273 --- /dev/null +++ b/tests/test_publisher_admission.py @@ -0,0 +1,39 @@ +"""Release tests use the checkout; the built distribution owns its metadata.""" + +import shlex +import tomllib +import zipfile +from email.parser import Parser +from pathlib import Path + +from packaging.requirements import Requirement +from setuptools import build_meta + + +ROOT = Path(__file__).resolve().parents[1] + + +def test_publisher_installs_the_dev_candidate_editably(): + workflow = (ROOT / ".github/workflows/publish.yml").read_text() + commands = [shlex.split(line.strip()) for line in workflow.splitlines()] + (install,) = [command for command in commands if ".[dev]" in command] + assert install[:4] == ["python", "-m", "pip", "install"] + assert install[install.index("-e") + 1] == ".[dev]" + assert "run: python -m pytest -q" in workflow + + +def test_editable_artifact_owns_checkout_path_and_roi_dev_requirement(tmp_path, monkeypatch): + monkeypatch.chdir(ROOT) + wheel = build_meta.build_editable(str(tmp_path)) + with zipfile.ZipFile(tmp_path / wheel) as archive: + (pth,) = [name for name in archive.namelist() if name.endswith(".pth")] + assert Path(archive.read(pth).decode().strip()).resolve() == ROOT / "src" + (metadata_name,) = [name for name in archive.namelist() if name.endswith("/METADATA")] + metadata = Parser().parsestr(archive.read(metadata_name).decode()) + project = tomllib.loads((ROOT / "pyproject.toml").read_text())["project"] + assert metadata["Name"] == project["name"] + assert metadata["Version"] == project["version"] + requirements = [Requirement(value) for value in metadata.get_all("Requires-Dist")] + (roi,) = [requirement for requirement in requirements if requirement.name == "roifile"] + assert roi.marker.evaluate({"extra": "dev"}) + assert not roi.marker.evaluate({"extra": ""})