Repository navigation
build: modernize tooling to uv, pyproject.toml, and semantic-release - #249
Merged
Merged
Conversation
salman2013
suggested changes
Sep 9, 2026
Migrate packaging and dependency management to the current Open edX standard so the repo stops depending on pip-compile and setup.py. - Replace setup.py/setup.cfg with PEP 621 pyproject.toml (setuptools-scm) - Switch pip-compile to uv with PEP 735 dependency groups; commit uv.lock - Retain flake8 as the quality linter - Update CI to astral-sh/setup-uv + uv run tox; SHA-pin all actions - Add release.yml (python-semantic-release + OIDC PyPI publishing) - Drop Python 3.11; set requires-python = ">=3.12" Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Publishing is handled by python-semantic-release and the PyPI publish workflow in CI, so the manual `make release` (twine upload) target is a redundant second release path and has been removed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The docs tox env now runs the same three builders master declared (html, doctest, linkcheck) with warnings treated as errors (-W). Master listed these but never ran them in CI, so they were dead and its doctest command was broken (sphinx.ext.doctest was never enabled); this now wires docs into CI and makes all three pass: - tox.ini: set SPHINXOPTS=-W and add the doctest and linkcheck commands - Makefile: pass -e to sub-make so SPHINXOPTS reaches docs/Makefile - docs/conf.py: enable sphinx.ext.doctest so the doctest builder registers - docs/index.rst: lengthen title underline (surfaced by -W) - docs/_static: add the directory referenced by html_static_path - README.rst: drop the dead pypip.in badge and repoint the 404 docs link Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove the [tool.semantic_release.commit_parser_options] override so PSR uses its default release tags (minor: feat; patch: fix, perf). public-engineering#506 states the "docs" minor_tags override is specific to the backend-plugin-sample example repo and that other libraries should use the default value unless there is a documented reason not to. enmerkar-underscore has none, so it follows the #506 default. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The docs had no static assets, so docs/_static/ existed only as an empty directory kept alive by a .gitkeep placeholder to satisfy conf.py's html_static_path = ['_static'] under the strict (-W) docs build. Remove both the placeholder and the now-pointless setting; Sphinx no longer looks for the directory and the -W html/doctest/linkcheck builds still pass. Matches how openedx/XBlock handles a repo with no static assets. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
farhan
force-pushed
the
farhan/modernize-python-repos
branch
from
September 10, 2026 07:58
08fdc08 to
36adf05
Compare
salman2013
suggested changes
Sep 10, 2026
salman2013
approved these changes
Sep 10, 2026
feanil
reviewed
Sep 23, 2026
Without this, the release job fails trying to write a changelog back to the repo. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
uv run --group test was re-syncing the environment to the test group on every tox invocation, overriding the Django version tox installed (e.g. django42 env silently ran Django 5.2 instead of 4.2). Tox manages the venv; the Makefile just runs commands inside it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous fix went too far — uv run without --group is fine and should be kept. Only --group re-syncs the environment and overrides the Django version tox installed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feanil
reviewed
Sep 24, 2026
bare `uv run` re-syncs to default groups before running, evicting whatever Django version tox-uv installed for the matrix leg. django42 was silently testing 5.2 as a result. Bare python/flake8 commands run in the tox-managed venv without re-syncing, so each matrix leg tests the correct Django version (verified: django42→4.2.30, django52→5.2.17). `uv run make test` still works for manual invocation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Per Feanil's guidance, Makefiles should not force/assume the uv environment. Developers activate the venv themselves; CI uses `uv run tox` in the workflow step. Strip `uv run` from all Makefile targets except `upgrade`. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Feanil noted this workflow must be kept — it uses the shared openedx/.github workflow which installs uv and runs plain `make upgrade` (the uv path). It does not depend on pip-compile. Removing it kills weekly automated dependency upgrades. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
source_pkgs resolves by import name regardless of where the package lives on disk, which is required for correct coverage measurement with a src/ layout. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
source_pkgs resolves by import name and silently drops packages that pytest never imports. source = ["src"] tracks every .py file under src/ by path regardless of imports. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Per Feanil's convention, the bare `py` env name should be used rather than the version-pinned `py312`. The python-version matrix entry in CI already pins the interpreter. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feanil
reviewed
Sep 29, 2026
feanil
left a comment
There was a problem hiding this comment.
One last thing and then this is good to go.
Without --locked, uv silently relocks when uv.lock is out of sync with pyproject.toml, hiding lockfile drift. With --locked, CI fails fast and forces developers to commit a fresh uv.lock before merge. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
feanil
approved these changes
Sep 30, 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.
Important
PR implemented with the assistance of Claude Code. Refined and validated before being submitted for code review.
Modernize
enmerkar-underscorePart of openedx/public-engineering#518
Summary
enmerkar-underscoreis published to PyPI: https://pypi.org/project/enmerkar-underscore/setup.py/setup.cfgwithpyproject.toml(PEP 621 static metadata)uvwith PEP 735 dependency groups; commituv.lockflake8as the quality linter, as on masterastral-sh/setup-uv, runuv run tox, and SHA-pin all actionspython-semantic-release+release.yml(OIDC trusted publishing), replacing the token-basedpublish_pypi.ymlsetuptools-scm;__version__reads it from package metadata at runtimerequires-python = ">=3.12"Removed/Updated
Deleted files:
setup.py,setup.cfg,requirements/Removed workflows:
publish_pypi.yml(replaced byrelease.yml),upgrade-python-requirements.yml(its pip-compile upgrade flow is replaced by theupgradeMakefile target runninguv lock --upgrade)Updated Makefile targets:
requirementsuv sync --group devupgradeedx_lint write_uv_constraints+uv lock --upgrade(dropped all pip-compile calls)lintflake8 src tests(previously targeted a non-existentdjango-babel-underscoredirectory)testpython -Wd -m pytest tests/(dropped removedsetup.py test)coveragesrc/enmerkar_underscoredocsmake -C docs html(droppedsphinx-apidocon a non-existent path)release/distpython -m build+twineinstead ofsetup.py sdist uploadPython 3.11 dropped
Removed Python 3.11 from the tox envlist, CI matrix, and classifiers; the target is 3.12.
Versioning
setuptools-scmwithdynamic = ["version"]— the repo publishes to PyPI, sopython-semantic-releasecontrols the version string at release time via git tags.__version__is exposed at runtime viaimportlib.metadata.Important Notes
commitlint.yml.pytest-pep8,pytest-flakes, andpython-coverallstest dependencies were dropped:pytest-pep8is incompatible with modern pytest (uses removed hook arguments), and its pep8/pyflakes checks are already covered byflake8in the quality env;python-coverallsis an unused, deprecated coveralls uploader.docs/conf.pycontained invalid Python (import django-babel-underscore,version = django-babel-underscore.__version__) that would fail any docs build; it now reads the version viaimportlib.metadata. Adocstox environment is now part of the CI matrix.make lintpreviously targeted a non-existent directory (effectively a no-op); now that it lintssrc tests, two pre-existing E302 blank-line issues were fixed.src/enmerkar_underscore/vendor/is excluded from flake8.src/layout on master; no layout change was needed.v2.4.1has been pushed sopython-semantic-releasecan correctly identify the latest release.Testing Notes
This PR has not been manually tested against the repo's own features. Testing relied on CI checks and local agent tooling (
make requirements,make lint,make test,python -m build). Repo-owner is encouraged to run the repo's feature tests before merging.🤖 Generated with Claude Code