Skip to content

feat: modernize Python tooling (pyproject.toml + uv + semantic-release)#242

Open
irfanuddinahmad wants to merge 10 commits into
mainfrom
irfanuddinahmad/uv-migration
Open

feat: modernize Python tooling (pyproject.toml + uv + semantic-release)#242
irfanuddinahmad wants to merge 10 commits into
mainfrom
irfanuddinahmad/uv-migration

Conversation

@irfanuddinahmad

@irfanuddinahmad irfanuddinahmad commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Modernizes this repo's Python tooling per the org-wide standardization tracked in openedx/public-engineering#513 (and the parent openedx/public-engineering#506):

  • Consolidate package metadata into pyproject.toml (PEP 621, setuptools-scm for git-tag-based versioning), replacing setup.py/setup.cfg
  • Switch dependency management from pip-compile to uv: requirements/*.in+*.txt are replaced by PEP 735 [dependency-groups] + a single uv.lock
  • Add python-semantic-release: pushes to main with conventional commits now automatically bump the version, tag it, and publish to PyPI (reusing the existing PYPI_UPLOAD_TOKEN secret)
  • Fix .readthedocs.yaml, which pointed at the now-deleted requirements/doc.txt

Part of openedx/public-engineering#513.

Test plan

  • uv lock resolves cleanly
  • uv build --wheel (with SETUPTOOLS_SCM_PRETEND_VERSION) succeeds, producing a correctly versioned wheel
  • Could not fully verify uv sync/uv run tox on my machine (no libmysqlclient/pkg-config locally to build mysqlclient from source) -- CI's ubuntu-latest runners have these preinstalled, so this needs verifying there.

Release readiness (pre-merge blocker)

  • PyPI trusted publisher (OIDC) configured for openedx-ledger
    → GitHub repo openedx/openedx-ledger, workflow release.yml
  • Confirmed working by:

Do not merge until both boxes are checked -- until then, publish_to_pypi will fail
on first merge to main (this PR switches the workflow to OIDC; it does not
configure the trusted publisher itself, which is a PyPI project-settings action with
no API we can drive from here). Tracked across this whole effort in a consolidated
comment on openedx/public-engineering#506.

🤖 Generated with Claude Code

@openedx-webhooks openedx-webhooks added open-source-contribution PR author is not from Axim or 2U core contributor PR author is a Core Contributor (who may or may not have write access to this repo). labels Jul 9, 2026
@openedx-webhooks

Copy link
Copy Markdown

Thanks for the pull request, @irfanuddinahmad!

This repository is currently maintained by @openedx/2u-enterprise.

Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review.

🔘 Get product approval

If you haven't already, check this list to see if your contribution needs to go through the product review process.

  • If it does, you'll need to submit a product proposal for your contribution, and have it reviewed by the Product Working Group.
    • This process (including the steps you'll need to take) is documented here.
  • If it doesn't, simply proceed with the next step.
🔘 Provide context

To help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:

  • Dependencies

    This PR must be merged before / after / at the same time as ...

  • Blockers

    This PR is waiting for OEP-1234 to be accepted.

  • Timeline information

    This PR must be merged by XX date because ...

  • Partner information

    This is for a course on edx.org.

  • Supporting documentation
  • Relevant Open edX discussion forum threads
🔘 Get a green build

If one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green.

Details
Where can I find more information?

If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources:

When can I expect my changes to be merged?

Our goal is to get community contributions seen and reviewed as efficiently as possible.

However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:

  • The size and impact of the changes that it introduces
  • The need for product review
  • Maintenance status of the parent repository

💡 As a result it may take up to several weeks or months to complete a review and merge your PR.

@github-project-automation github-project-automation Bot moved this to Needs Triage in Contributions Jul 9, 2026
@mphilbrick211 mphilbrick211 moved this from Needs Triage to Ready for Review in Contributions Jul 13, 2026
@mphilbrick211

Copy link
Copy Markdown

Hi @irfanuddinahmad! Would you mind taking a look at the branch conflicts that have popped up? Thanks!

Irfan Ahmad and others added 9 commits July 17, 2026 15:10
Replace setup.py/setup.cfg with PEP 621 [project] metadata and
setuptools-scm for git-tag-based versioning.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replace requirements/*.in + *.txt with PEP 735 dependency-groups in
pyproject.toml and a single uv.lock. Update tox.ini to use tox-uv's
uv-venv-runner/uv-venv-lock-runner, update Makefile targets, and
fix .readthedocs.yaml to install docs deps via uv.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replace the manual GitHub-release-triggered publish workflow with
python-semantic-release: pushes to main with conventional commits
now automatically bump the version, tag it, and publish to PyPI.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… MANIFEST.in entries

semantic-release defaults to a "v{version}" tag format, but this repo's
existing release tags are bare version numbers -- without tag_format set,
semantic-release wouldn't recognize any prior release.

packages.find.exclude only stops setuptools from registering the tests
subpackage; with include-package-data=true it still swept tests/*.py into
the wheel as package_data. Verified: built wheels before/after this fix --
tests/__init__.py and tests/test_views.py were present in the wheel prior
to this commit and are absent after, while test_utils/ (the intentionally
shipped factories module) is unaffected.

Also removes MANIFEST.in references to requirements/base.in and
requirements/constraints.txt, which no longer exist after the uv migration.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Every uv sync/uv run invocation in this repo names an explicit --group,
but uv's implicit default group (named "dev") was still being synced
alongside it, silently pulling the entire dev/test/quality/ci superset
into every target.

Also adds venv/ and .venv/ to .gitignore (previously absent).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Parent issue openedx/public-engineering#506 asks for OIDC trusted-publisher
PyPI auth, not a stored token. Grant id-token: write on publish_to_pypi and
drop the explicit __token__/PYPI_UPLOAD_TOKEN credentials -- pypa/gh-action-pypi-publish
uses OIDC automatically once the permission is present and no credentials are given.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@release/v1 is a floating branch ref -- xblocks-core's release just failed
with "docker: manifest unknown" because the Docker image tag it resolved to
at checkout time wasn't published on ghcr.io yet. Pin to the exact commit
backing the current v1.14.0 release instead, consistent with this repo's
own SHA-pinning rule for every other action.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Reviewer feedback: this should be set across the whole batch, not just
repos currently on 0.x, so no repo in this effort can ever auto-jump to
1.0.0 as an accidental side effect if it's reset to 0.x in the future.
Note this is a no-op for repos already past 1.0 -- major_on_zero only
governs the 0.x -> 1.0.0 transition, not 1.x -> 2.0.0 (there's no PSR
setting that suppresses major bumps once past 1.0; that's normal SemVer
behavior for a breaking-change commit at any version).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Moves openedx_ledger/ to src/openedx_ledger/, in line with the reference
implementation for this modernization effort (openedx/sample-plugin)
and openedx/forum#281.

- pyproject.toml: add where = ["src"] to packages.find
- tox.ini: prefix src/ onto the quality env's pylint/pycodestyle/isort
  targets
- Makefile: prefix src/openedx_ledger onto the standalone isort/style/lint
  targets and the 5 localization targets that cd into the package;
  extract_translations/compile_translations' relative ../manage.py climbs
  updated to ../../manage.py to account for the extra nesting level
- test_settings.py: LOCALE_PATHS root() call updated
- docs/conf.py: sphinx-apidoc call updated to point at src/openedx_ledger
- MANIFEST.in: recursive-include path updated
- Dockerfile needs no change: it COPYs the whole repo rather than naming
  the package directory directly

Verified: uv build --wheel + twine check pass (direct proof the
where=["src"] packaging change works). Could not run the full
pytest/quality/docs tox matrix locally -- this machine has no
libmysqlclient/pkg-config to build the mysqlclient C extension (a
[project.dependencies] entry, so it's required for every uv sync
regardless of group), same environment limitation hit previously on
enterprise-access. Relying on CI for full-matrix confirmation.
@irfanuddinahmad
irfanuddinahmad force-pushed the irfanuddinahmad/uv-migration branch from a01e192 to 3e3ac11 Compare July 17, 2026 10:15
@farhan

farhan commented Jul 17, 2026

Copy link
Copy Markdown

tests are failing

CI failed after the src-layout move: pytest raised ModuleNotFoundError
for openedx_ledger.tests when collecting src/openedx_ledger/tests/test_views.py.

Root cause: these two envs were the only ones in this repo still using
tox-uv's non-lock uv-venv-runner, which builds and installs a real
(non-editable) sdist for testing. That build genuinely excludes
openedx_ledger.tests per packages.find(exclude=["*tests"]) -- correct
for the published PyPI wheel, wrong for a test run. In flat layout this
was masked because the sdist-installed copy in site-packages was shadowed
on sys.path by the physically-identical openedx_ledger/ directory at repo
root; moving the package under src/ removes that accidental shadow (the
exact masking effect the src-layout/flat-layout packaging guide warns
about), so the real gap surfaced. docs/quality already used
uv-venv-lock-runner (uv sync, editable install) and were unaffected.

Verified the fix mechanism in an isolated repro (same packages.find
exclude pattern, in-package tests subpackage, tox + tox-uv): switching
uv-venv-runner -> uv-venv-lock-runner changes the install from a built
sdist to `uv sync`'s editable install, and the ModuleNotFoundError goes
away. Could not run the real repo's tox matrix locally (mysqlclient
build environment limitation) -- pushing to confirm via CI.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core contributor PR author is a Core Contributor (who may or may not have write access to this repo). open-source-contribution PR author is not from Axim or 2U

Projects

Status: Ready for Review

Development

Successfully merging this pull request may close these issues.

4 participants