build: migrate CI and service images from Poetry to uv#2152
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR hardens the CI workflow against indefinite hangs during Poetry dependency resolution by adding explicit timeouts and ensuring Poetry runs non-interactively, improving reliability of the test matrix runs across Presidio components.
Changes:
- Add a job-level timeout (
timeout-minutes: 60) for the matrixtestjob to prevent unbounded runtime. - Add a step-level timeout (
timeout-minutes: 30) specifically for the “Install dependencies” step to cap Poetry resolution time. - Add
--no-interactiontopoetry installto avoid CI waiting on prompts.
Contributor
Coverage report (presidio-anonymizer)Click to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||||||||||||||
Contributor
Coverage report (presidio-image-redactor)Click to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||||||||||||||
Contributor
Coverage report (presidio-cli)Click to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||
Contributor
The analyzer test job runs `poetry install --all-extras` with no committed lock, so Poetry performs a universal resolve of the full optional-dependencies graph on every run. That resolve backtracks for many minutes — effectively hanging — driven by the langextract extra's deep, loosely-bounded transitive tree. Reproduced locally: Poetry >6 min (never completed); uv ~2s for the same 158-package resolution. Switch the test jobs to uv: - Install uv via astral-sh/setup-uv. - Create a per-component venv with `uv venv --seed` (seed keeps pip for the wheel-build step) and expose it via $GITHUB_PATH / $VIRTUAL_ENV. - `uv pip install -e '.<extras>'` plus the test tooling that previously came from the Poetry dev group (uv does not read that group). - Add a job-level `timeout-minutes: 60` (and 30 on the install step) so a bad resolve fails fast instead of hanging. No package metadata changed — pyproject.toml is untouched; this only swaps the CI install tooling. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
a029bf8 to
7340a02
Compare
omri374
reviewed
Jul 12, 2026
Use "uv run --no-sync" for spaCy model downloads, pytest, and diff-cover instead of exposing the venv on $GITHUB_PATH. "uv sync" builds the project's .venv (resolving the analyzer --all-extras graph in seconds where Poetry's lockless universal resolve hangs), and the subsequent steps execute inside it idiomatically. The --all-extras selection stays in the job matrix, unchanged from main. Wheel-build keeps using the system interpreter, matching the previous Poetry behaviour. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The astral-sh/setup-uv action is not on the org's allowed-actions list, so adding it made the CI workflow fail at startup (startup_failure) before any job ran. Install a pinned uv from PyPI with the already present setup-python instead; this needs no new third-party action and keeps the resolver benefits that motivated the Poetry -> uv switch. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
spaCy's `download` command shells out to `python -m pip install`, but uv-created virtualenvs ship without pip, so runtime/first-use model downloads (e.g. the presidio-cli conftest fetching en_core_web_lg) failed with SystemExit: 1. Install pip alongside the test tooling. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SharonHart
previously approved these changes
Jul 12, 2026
Address review feedback:
- ci.yml: use ${{ env.UV_CACHE_DIR }} for the cache action path instead of
hardcoding /mnt/uv-cache, so the cache and uv stay in sync if the dir
changes.
- copilot-instructions: update the "Technology Stack" bullet to name uv as
the dependency/install tool (poetry-core retained only as build backend),
matching the uv-based dev commands already documented.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Trim the verbose explanatory comments in the test job to 1-3 lines each, and drop the dependency-review `allow-ghsas` entry for the transformers advisories. That suppression is a security concern rather than part of the Poetry->uv migration, so it moves to the stacked security PR alongside the .trivyignore. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove `cache: 'pip'` (keyed on pyproject.toml) from the test job's setup-python: it is leftover Poetry-era config. Project dependencies now use the uv cache, and the only remaining pip installs (uv, tomli, build tools) are tiny and unrelated to pyproject.toml. Also condense the unreleased CHANGELOG entry to a single concise line; the implementation detail lives in the PR description. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment on lines
+198
to
202
| # `build` needs tomli on Python < 3.11 to read pyproject.toml, and it | ||
| # isn't in the hashed requirements file; pre-install it (marker-guarded) | ||
| # so --require-hashes finds it already satisfied. | ||
| python -m pip install "tomli==2.4.1; python_version < '3.11'" | ||
| pip install --require-hashes -r ${{ github.workspace }}/.github/pipelines/requirements-build.txt |
SharonHart
approved these changes
Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Change Description
Migrates the repository's CI and service-image dependency installation from Poetry to uv, with committed lockfiles. This is the first, self-contained step toward a fully uv-based repo (a fuller migration — build backend, remaining Dockerfile variants, docs — is tracked as follow-up work).
Why: CI installed dependencies with
poetry installand no committed lock, so Poetry ran a universal resolve of the wholeoptional-dependenciesgraph on every run. That resolve backtracked for many minutes — effectively hanging — on the analyzer's--all-extrasgraph (dominated by thelangextractextra's deep transitive tree). The same pathology hit the local-build/E2E job, wheredocker compose buildsat on "Resolving dependencies" for ~40 min. Reproduced locally: Poetry >6 min, never completed; uv resolves the same graph in ~2s.What changed
Packaging (the 5 CI-tested packages):
[tool.poetry.group.dev.dependencies]to the standard PEP 735[dependency-groups]table —pyproject.tomlis now the single source of truth for dev tools.uv.lock(**/uv.lockadded to CODEOWNERS; contributor docs require regenerating it when deps change).[project]metadata is otherwise unchanged, and thepoetry-corebuild backend is retained for now, so published wheels/sdists are identical.CI (
.github/workflows/ci.yml):pip install uv==0.11.6(theastral-sh/setup-uvaction isn't on the org allow-list — it caused a workflowstartup_failure).uv sync --locked --group dev— installs exactly the locked graph and fails onpyproject/uv.lockdrift (no resolution or lockfile mutation in CI). This replaces the manualuv pip install pytest …line.uv run --no-sync; the wheel-build step keeps using the system interpreter.actions/cachekeyed onuv.lock, trimmed withuv cache prune --ci) on the/mntdisk.timeout-minutessafety net so a bad resolve fails fast instead of hanging.Service images (analyzer / anonymizer / image-redactor):
Dockerfiles install withuv sync --locked --no-default-groups --extra server --no-install-projectintoUV_PROJECT_ENVIRONMENT=/usr/local, so images use the same locked graph as CI. The dependency layer is split from the sourceCOPYfor caching.entrypoint.shrunsgunicorndirectly (deps are on the system PATH; nopoetry run).Verified: all 22 test-matrix jobs (incl. Python 3.14) and the local-build/E2E job pass; the E2E image build dropped from a ~40 min hang to ~2.5 min. Service containers start healthy (
/health→ 200).Issue reference
N/A
Checklist