Skip to content

ci: gate publish on cross-platform tests; bump dep floors#231

Merged
vietanhdev merged 4 commits intomasterfrom
ci/test-gate-and-deps-upgrade
Apr 25, 2026
Merged

ci: gate publish on cross-platform tests; bump dep floors#231
vietanhdev merged 4 commits intomasterfrom
ci/test-gate-and-deps-upgrade

Conversation

@vietanhdev
Copy link
Copy Markdown
Owner

@vietanhdev vietanhdev commented Apr 25, 2026

Summary

  • Adds .github/workflows/tests.yml — a 3×3 matrix (Ubuntu/Windows/macOS × Python 3.11/3.12/3.13) that runs pip install . and the unit suite. Reusable via workflow_call.
  • Gates python-publish-cpu.yml, python-publish-gpu.yml, and release.yml on the matrix via needs: test. Tag-driven publishes now wait for tests across every supported Python and OS.
  • Bumps action versions: actions/checkout v2/v3 → v4, actions/setup-python v4 → v5, conda-incubator/setup-miniconda v2 → v3.
  • Raises pyproject.toml dependency floors to versions verified to install cleanly on all three Pythons; adds a missing huggingface_hub>=0.24.0 floor.
  • Adds CLAUDE.md (six-step pre-publish playbook + architecture overview) and rewrites .cursorrules to mirror it.
  • Fixes resource scripts post-PyQt6 migration. scripts/compile_languages.py and scripts/generate_languages.py shelled out to pyrcc5 / pyrcc6 — neither exists in PyQt6. Both have been broken since 9735fe8. Switch to pyside6-rcc + pyside6-lrelease and rewrite the generated imports back to PyQt6. Add PySide6-Essentials as a [dev] extra.
  • Fixes the GPU publish path. The setup.py shim that overrides the package name to anylabeling-gpu is silently rejected by PEP 621 (pyproject.toml's [project].name is static). A tag push today would build anylabeling-0.4.x.whl and try to upload it via the anylabeling-gpu trusted-publisher token — PyPI would reject. Have the GPU workflow sed pyproject.toml directly before python -m build, and add a verify step that asserts the wheel filename + METADATA.

Why

anylabeling-gpu==0.4.30 shipped to PyPI broken (#227) because no automated step ran pip install . against current dep floors before publish. The fix landed on master, but nothing in CI would have caught the next similar regression. This PR closes that gap and surfaces two more pre-existing breakages on the way (resource scripts, GPU publish path).

What was actually verified

  • 9-cell test matrix passes on this PR (Ubuntu/Windows/macOS × py3.11/3.12/3.13).
  • Local install + unit suite + real-model inference on Python 3.11.15 / 3.12.13 / 3.13.9 against the bumped floors: MobileSAM (3 tests), SAM2 hiera-tiny (4 tests), SAM3 ViT-H (6 tests), YOLOv8n (3 tests).
  • CPU wheel build (python -m build) produces Name: anylabeling, METADATA reflects bumped floors.
  • GPU wheel build with the new sed step produces Name: anylabeling-gpu and Requires-Dist: onnxruntime-gpu>=1.20.0 (verified locally; before this PR the same steps produced Name: anylabeling).
  • Resource scripts run end-to-end under PyQt6: python scripts/compile_languages.py rebuilds anylabeling/resources/resources.py and the full app import chain still loads.
  • Publish workflows did NOT run on this branch pushpython-publish-{cpu,gpu}.yml and release.yml are gated by on: push: tags: 'v*', so opening a PR cannot accidentally publish to PyPI.

What this PR does NOT exercise

The publish/release workflows only run on tag pushes, so the only true end-to-end proof of the gate + GPU rewrite is to push a real tag. Verified statically:

  • python-publish-cpu.yml: build-n-publish declares needs: test.
  • python-publish-gpu.yml: build-n-publish-gpu declares needs: test; new sed + verify steps confirm the wheel is anylabeling-gpu before upload.
  • release.yml: release declares needs: test; build and build_macos_folder declare needs: [release].

Follow-ups (separate PRs)

  • Delete the now-no-op setup.py shim — its name override is silently dropped by PEP 621; the pyproject.toml sed in CI is the authoritative mechanism now.
  • Decide whether to delete .cursorrules (kept and rewritten in this PR).

Adds .github/workflows/tests.yml that runs the unit suite on a 3x3
matrix (Ubuntu/Windows/macOS x Python 3.11/3.12/3.13). The CPU and GPU
PyPI publish workflows and the release workflow now declare needs: test
so the matrix gates every tag-driven artifact.

Bumps action versions across all workflows: actions/checkout v2/v3 to
v4, actions/setup-python v4 to v5, conda-incubator/setup-miniconda v2
to v3.

Raises pyproject.toml dependency floors to versions known to install
cleanly on every supported Python:
  natsort        >= 8.0.0  -> >= 8.4.0
  Pillow         >= 10.0.0 -> >= 11.0.0
  termcolor      >= 2.0.0  -> >= 2.4.0
  PyQt6          >= 6.5.0  -> >= 6.7.0
  huggingface_hub  unbounded -> >= 0.24.0
  osam           >= 0.3.1  -> >= 0.4.0

Adds CLAUDE.md with architecture overview and a six-step pre-publish
playbook (fresh-venv install, unit tests, real-model inference,
startup smoke test, multi-Python repeat, then push).

Context: anylabeling-gpu==0.4.30 shipped to PyPI broken because no
automated step ran pip install . against current dep floors before
publish. The crash (#227) had a regression test on master, but nothing
executed it on the publish path. This change closes that gap.
The first matrix run failed on every Linux and macOS cell:

- Linux: PyQt6 wheels need libEGL and a handful of XCB system libraries
  that GitHub's ubuntu-latest runner does not install by default
  (ImportError: libEGL.so.1: cannot open shared object file). Add an
  apt-get step that installs the Qt6 runtime deps before pip install.

- macOS: pyproject.toml intentionally excludes PyQt6 on Darwin
  (PyQt6>=6.7.0; platform_system != 'Darwin') because end-users install
  it through conda. The CI runner has no conda, so unittest collection
  fails with ModuleNotFoundError: No module named 'PyQt6'. Add a step
  that pip-installs PyQt6 only on macOS to mirror the conda install.

- All: set QT_QPA_PLATFORM=offscreen at the job level so Qt does not
  try to open a display when imported.

Windows already passed.
…DE.md

scripts/compile_languages.py and scripts/generate_languages.py both
shelled out to pyrcc5 / pyrcc6, neither of which exists in PyQt6
(the Qt project removed the standalone resource compiler in Qt 6).
Both scripts have been broken since the PyQt6 migration in 9735fe8 —
nobody noticed because anylabeling/resources/resources.py is committed
and rarely regenerated.

Switch to pyside6-rcc and pyside6-lrelease (PySide6 still ships them)
and rewrite the generated imports from PySide6 to PyQt6. Also resolve
tools next to sys.executable so the scripts work whether or not the
venv bin is on PATH.

Add PySide6-Essentials to the [dev] extras — it is a dev-time tool
only; runtime has no PySide6 dependency.

Verified end to end: python scripts/compile_languages.py produces an
updated resources.py that the full app import chain loads cleanly.
The regenerated resources.py is not included in this commit (large
binary diff, no functional change against the working tree).

.cursorrules was a 4-line stub. Replace it with a focused mirror of
CLAUDE.md: PyQt6 / Darwin marker convention, architecture cheat sheet,
the pre-publish gate, and the new resource-regeneration story.
…-gpu

setup.py was the previous mechanism that overrode the package name to
'anylabeling-gpu' and swapped onnxruntime -> onnxruntime-gpu, but PEP 621
requires the [project].name in pyproject.toml to be static. The setup()
override is silently ignored by the modern build backend, so a tag push
today would build a wheel named 'anylabeling-0.4.34' and try to upload
it via the trusted-publisher token scoped to 'anylabeling-gpu' — PyPI
would reject the upload.

Verified locally:
  before: python -m build => Name: anylabeling, onnxruntime>=1.20.0
  after  (with these seds applied):
          python -m build => Name: anylabeling-gpu, onnxruntime-gpu>=1.20.0
          wheel filename:    anylabeling_gpu-0.4.30-py3-none-any.whl

Add a verify step that asserts the wheel filename and METADATA after
the build so this can never silently regress again. Leave setup.py
untouched — it is now no-op but harmless; clean it up in a follow-up.

The actual published anylabeling-gpu==0.4.30 still has PyQt5 metadata
(setup.py-era), confirming this code path has not produced a working
wheel since the pyproject.toml refactor in 59c3044.
@vietanhdev vietanhdev merged commit 1591cd6 into master Apr 25, 2026
9 checks passed
@vietanhdev vietanhdev deleted the ci/test-gate-and-deps-upgrade branch April 25, 2026 03:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant