Skip to content

feat: migrate from PDM to uv package manager#202

Merged
JonnyTran merged 13 commits intodevelopfrom
feat/uv-package-manager
Mar 25, 2026
Merged

feat: migrate from PDM to uv package manager#202
JonnyTran merged 13 commits intodevelopfrom
feat/uv-package-manager

Conversation

@JonnyTran
Copy link
Copy Markdown
Member

Summary

  • Switch build backend from pdm-backend to hatchling for both extralit and extralit-server
  • Move dev dependencies to PEP 735 [dependency-groups]
  • Update all CI workflows to use uv sync/uv build/uv run/uv publish instead of PDM
  • Keep [tool.pdm.scripts] in extralit-server for local dev convenience (Docker start script unaffected)

Test plan

  • extralit CI workflow passes (multi-Python matrix: 3.9–3.13)
  • extralit-server CI workflow passes (build + tests)
  • Docs workflow parses correctly
  • Docker image build workflow parses correctly

🤖 Generated with Claude Code

Switch build backend from pdm-backend to hatchling for both packages.
Move dev dependencies to PEP 735 dependency-groups. Update all CI
workflows to use uv sync/build/run/publish instead of PDM commands.
Keep [tool.pdm.scripts] in extralit-server for local dev convenience.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@JonnyTran JonnyTran requested review from a team as code owners March 25, 2026 15:42
Comment thread .github/workflows/extralit-server.build-docker-images.yml Fixed
Comment thread .github/workflows/extralit-server.yml Fixed
JonnyTran and others added 12 commits March 25, 2026 08:48
- Remove uv.lock from .gitignore so lock files are committed
- Add uv.lock for both extralit and extralit-server
- Use --group test for extralit-server uv sync in CI
- Move env vars from shell variables to workflow env blocks
- Add .env.test equivalent env vars to extralit workflow

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The PostgreSQL optional dependency (psycopg2) is needed for tests
to import the server modules. Unlike PDM which installs all optional
deps by default, uv sync requires explicit --extra flags.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove deprecated event_loop fixture, add loop_scope="session" for
session-scoped async fixtures, and use .get() for UserInfo.username
to prevent KeyError when username is missing from OAuth user data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tests must also use the session-scoped event loop to match the
session-scoped asyncpg connection, preventing "attached to a different
loop" and "another operation is in progress" errors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The asyncio_default_test_loop_scope=session caused "no current event
loop in thread MainThread" errors in pytest-asyncio's wrap_in_sync.
Restore the session-scoped event_loop fixture to properly set the loop
on the main thread, while keeping fixture loop_scope=session.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The username property now returns "" instead of raising KeyError
when username claim is missing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
pytest-asyncio 1.x removed native support for the session-scoped
event_loop fixture pattern used throughout the test suite. Downgrade
to 0.24.x which properly supports this pattern, fixing asyncpg
"attached to different loop" errors when running against PostgreSQL.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CLI commands like create_default use asyncio.run() which closes and
unsets the current event loop. Add autouse fixture to restore the
session event loop after each test, preventing cascading "no current
event loop" failures in subsequent tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Switch back to pytest-asyncio 1.x with proper session loop scope for
both fixtures and tests. Add autouse _ensure_event_loop fixture that
sets an event loop on the main thread before/after each test, handling
both pytest-asyncio 1.x session scope and CLI asyncio.run() teardown.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The _ensure_event_loop fixture was creating new event loops that
conflicted with pytest-asyncio's session loop, causing "attached to
different loop" errors. Instead, save the loop before each test and
restore it after, so asyncio.run() in CLI tests can't permanently
destroy the event loop state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace RuntimeError with AuthenticationError so the exception handler
returns a proper 401 response instead of propagating as unhandled 500.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaced the version tag for the setup-uv action with a specific commit hash across multiple workflow files to ensure consistent behavior and avoid potential issues with future updates.
@JonnyTran JonnyTran merged commit 1e231af into develop Mar 25, 2026
4 of 9 checks passed
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.

2 participants