Conversation
Split out of farhan/modernize-repo; ruff retained there for adoption in a future epic (per public-engineering#506). - Replace setup.py/setup.cfg with pyproject.toml (PEP 621 static metadata) - Switch from pip-compile to uv with PEP 735 dependency groups; commit uv.lock - Retain pylint/isort/pycodestyle/pydocstyle as on master (ruff deferred) - Update tox.ini to use tox-uv with uv-venv-lock-runner - Update CI to use astral-sh/setup-uv; SHA-pin all actions; add workflow_call trigger - Add python-semantic-release + release.yml (OIDC trusted publishing) - Add commitlint.yml to enforce conventional commit format on all future PRs Part of openedx/public-engineering#506
…warning - Run isort on all source files to fix import ordering (isort v8 is stricter than the pre-migration version; files not yet sorted) - Remove black --check from tox quality env (black was not in requirements/quality.in on master so was never reliably enforced) - Remove black from quality dependency group accordingly - Add ref.python to suppress_warnings in docs/conf.py to silence the ambiguous cross-reference warning for the `type` attribute (present in both Content and ContentSerializer); Sphinx 9.x treats this as an error with -W Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace PYPI_UPLOAD_TOKEN with id-token: write + pypa/gh-action-pypi-publish (no password input). OIDC is the org-wide standard per public-engineering#506, unconditionally applied regardless of what master used. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Repo is on 0.4.3 (0.x). Without allow_zero_version=true and major_on_zero=false, the first feat: commit after merge would bump 0.x.y → 1.0.0 unexpectedly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moves the importable package from forum/ to src/forum/ per the modernization standard (public-engineering#520). Updates all tooling references: setuptools find, coverage source_pkgs, tox quality/mypy envs, Makefile targets, and docs/conf.py apidoc paths. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
black was in master's ci.in but was not carried over to any dependency group in pyproject.toml, leaving the `format` target broken (uv run black fails with no such file or directory). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moves channel_integrations/ to src/channel_integrations/, 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 pylint/pycodestyle targets in the quality env - Makefile: prefix src/ onto all 5 localization targets (extract, compile, detect_changed, pull, dummy); atlas pull's local destination path updated, remote Transifex identifier left unchanged - test_settings.py: LOCALE_PATHS root() call updated - docs/conf.py: sphinx-apidoc call updated to point at src/channel_integrations - MANIFEST.in: recursive-include path updated Verified: uv sync (no lock drift), full django42 test run (893 passed), quality and pii_check envs pass, uv build --wheel + twine check pass. The docs tox env fails both before and after this change (a pre-existing sphinx/autodoc ValueError in object_description, unrelated to src-layout and unrelated to this repo's file layout) -- confirmed by reproducing the identical failure on the pre-migration commit via git stash.
Moves taxonomy/ to src/taxonomy/, 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 pylint/pycodestyle/pydocstyle/isort targets in the quality env - Makefile: prefix src/taxonomy onto the 3 localization targets that cd into the package (compile_translations, detect_changed_source_translations, dummy_translations); compile_translations' relative ../manage.py climb 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/taxonomy - MANIFEST.in: recursive-include path updated Verified: uv sync (no lock drift), full django42 test run (315 passed), quality (pylint/pycodestyle/pydocstyle/isort) and pii-annotations envs pass, docs env passes end to end -- sphinx-apidoc generates real API docs from the new path, uv build --wheel + twine check pass.
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.
Moves all three top-level packages (enterprise_data, enterprise_data_roles, enterprise_reporting) to src/, 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 isort/pylint/pycodestyle/ pydocstyle targets, and onto the data env's pytest --ignore path and the reporting env's test-collection path (--cov's own module-name arg is left alone -- it resolves via the installed module, not a filesystem path). DJANGO_SETTINGS_MODULE=enterprise_data.settings.test is an import path, unaffected by the physical move. - Makefile: prefix src/ onto the isort target's package names - MANIFEST.in: all three recursive-include paths updated - enterprise_data/settings/test.py: this repo's in-package here()/root() path helper climbs from src/enterprise_data/settings/ back to the repo root -- fixed the climb from '../..' (2 levels, correct pre-move) to '../../..' (3 levels, correct post-move) so root() still means what its docstring says. root() has no current call sites (dead code), but fixed the definition itself for correctness -- verified by direct invocation that it now resolves to the true repo root. Verified: uv sync (no lock drift), uv build --wheel + twine check pass (direct proof the where=["src"] packaging change works across all three packages). Could not run the full tox matrix locally -- this machine's clang/zlib toolchain can't build pyminizip (a native extension in the "reporting" extra that both the "test" and "quality" dependency groups pull in), unrelated to src-layout. Relying on CI for full-matrix confirmation.
Moves all four top-level packages (enterprise, consent, integrated_channels, enterprise_learner_portal) to src/, in line with the reference implementation for this modernization effort (openedx/sample-plugin) and openedx/forum#281. Most complex repo in this batch: 4 packages, an in-package path helper with real call sites, and JS tooling (webpack, jasmine) alongside the Python side. - pyproject.toml: add where = ["src"] to packages.find - tox.ini: prefix src/ onto the pycodestyle exclude list and onto every package name in the isort/isort-check/quality env commands - Makefile: prefix src/ onto clean.static, dummy_translations, pull_translations (local destination paths only -- the Transifex/Atlas remote path identifiers are left unchanged), jshint, pylint, pycodestyle, isort, and isort-check targets - docs/conf.py: sphinx-apidoc call updated to point at src/enterprise - webpack.config.js: build context path updated to src/enterprise/static/enterprise - spec/javascripts/support/jasmine.yml: src_files glob updated to src/enterprise/static/enterprise/js/*.js - MANIFEST.in: all four recursive-include paths and the enterprise/locale symlink exclusion updated - enterprise/settings/test.py: this repo's in-package here()/root() path helper climbs from src/enterprise/settings/ back to the repo root -- fixed the climb from '../..' (2 levels) to '../../..' (3 levels), and updated its 3 real call sites (LOCALE_PATHS, REPO_ROOT, STATIC_ROOT) to prepend 'src' so they still resolve inside the package. The symlink enterprise/locale -> conf/locale is relative and moved as a unit with git mv, so it still resolves correctly post-move -- verified. Verified: uv sync (no lock drift), full py312-django52 test run (2849 passed), quality (pylint/pycodestyle/isort), isort-check, and pii_check envs pass, docs env passes end to end -- sphinx-apidoc generates real API docs from the new path, uv build --wheel + twine check pass. A pylint useless-suppression info note in integrated_channels/cornerstone/models.py is pre-existing (confirmed identical on the pre-migration commit via git stash), unrelated to this change.
CI pins the interpreter via setup-uv's python-version; the explicit basepython = python3.12 is unnecessary. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
irfanuddinahmad
left a comment
There was a problem hiding this comment.
Reviewed the modernization changes (uv/pyproject.toml + src-layout + semantic-release migration). OIDC publishing and action pinning look correct; no issues found.
Per review feedback, remove the >=61.0 minimum to stay consistent with how other modernized openedx repos declare their build-system. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moves all four top-level packages (enterprise, consent, integrated_channels, enterprise_learner_portal) to src/, in line with the reference implementation for this modernization effort (openedx/sample-plugin) and openedx/forum#281. Most complex repo in this batch: 4 packages, an in-package path helper with real call sites, and JS tooling (webpack, jasmine) alongside the Python side. - pyproject.toml: add where = ["src"] to packages.find - tox.ini: prefix src/ onto the pycodestyle exclude list and onto every package name in the isort/isort-check/quality env commands - Makefile: prefix src/ onto clean.static, dummy_translations, pull_translations (local destination paths only -- the Transifex/Atlas remote path identifiers are left unchanged), jshint, pylint, pycodestyle, isort, and isort-check targets - docs/conf.py: sphinx-apidoc call updated to point at src/enterprise - webpack.config.js: build context path updated to src/enterprise/static/enterprise - spec/javascripts/support/jasmine.yml: src_files glob updated to src/enterprise/static/enterprise/js/*.js - MANIFEST.in: all four recursive-include paths and the enterprise/locale symlink exclusion updated - enterprise/settings/test.py: this repo's in-package here()/root() path helper climbs from src/enterprise/settings/ back to the repo root -- fixed the climb from '../..' (2 levels) to '../../..' (3 levels), and updated its 3 real call sites (LOCALE_PATHS, REPO_ROOT, STATIC_ROOT) to prepend 'src' so they still resolve inside the package. The symlink enterprise/locale -> conf/locale is relative and moved as a unit with git mv, so it still resolves correctly post-move -- verified. Verified: uv sync (no lock drift), full py312-django52 test run (2849 passed), quality (pylint/pycodestyle/isort), isort-check, and pii_check envs pass, docs env passes end to end -- sphinx-apidoc generates real API docs from the new path, uv build --wheel + twine check pass. A pylint useless-suppression info note in integrated_channels/cornerstone/models.py is pre-existing (confirmed identical on the pre-migration commit via git stash), unrelated to this change.
Moves all three top-level packages (enterprise_data, enterprise_data_roles, enterprise_reporting) to src/, 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 isort/pylint/pycodestyle/ pydocstyle targets, and onto the data env's pytest --ignore path and the reporting env's test-collection path (--cov's own module-name arg is left alone -- it resolves via the installed module, not a filesystem path). DJANGO_SETTINGS_MODULE=enterprise_data.settings.test is an import path, unaffected by the physical move. - Makefile: prefix src/ onto the isort target's package names - MANIFEST.in: all three recursive-include paths updated - enterprise_data/settings/test.py: this repo's in-package here()/root() path helper climbs from src/enterprise_data/settings/ back to the repo root -- fixed the climb from '../..' (2 levels, correct pre-move) to '../../..' (3 levels, correct post-move) so root() still means what its docstring says. root() has no current call sites (dead code), but fixed the definition itself for correctness -- verified by direct invocation that it now resolves to the true repo root. Verified: uv sync (no lock drift), uv build --wheel + twine check pass (direct proof the where=["src"] packaging change works across all three packages). Could not run the full tox matrix locally -- this machine's clang/zlib toolchain can't build pyminizip (a native extension in the "reporting" extra that both the "test" and "quality" dependency groups pull in), unrelated to src-layout. Relying on CI for full-matrix confirmation.
| ) | ||
| from .subscriptions import create_subscription, delete_subscription, get_thread_subscriptions, get_user_subscriptions | ||
| from .threads import create_thread, delete_thread, get_course_id_by_thread, get_thread, get_user_threads, update_thread | ||
| from .users import (create_user, delete_user_posts, get_user, get_user_active_threads, get_user_course_stats, |
There was a problem hiding this comment.
A lot of imports are going from one per line to this multi-line format which seems less readable to me. Is this because of isort? is there something wrong with the config causing this? I think we prefer multi-line imports with one import per line over this version. Let's update the config so that we don't do this kind of change if we can.
|
|
||
| upgrade: ## update the requirements/*.txt files with the latest packages satisfying requirements/*.in | ||
| $(MAKE) compile-requirements COMPILE_OPTS="--upgrade" | ||
| lint: ## Run linting checks |
There was a problem hiding this comment.
| lint: ## Run linting checks | |
| quality: ## Run linting and other quality checks |
|
|
||
| requirements: clean_tox piptools ## install development environment requirements | ||
| pip-sync -q requirements/dev.txt requirements/private.* | ||
| format: ## Auto-fix formatting issues |
There was a problem hiding this comment.
Why was this updated to only format prod files instead of all the files?
| DJANGO_SETTINGS_MODULE = forum.settings.test | ||
| commands = | ||
| make test-pii | ||
| code_annotations django_find_annotations --config_file .pii_annotations.yml --lint --report --coverage |
There was a problem hiding this comment.
We sholud be calling make targets from inside tox so that we can run those targets outside of tox easily as well in a re-producable way. We sholudn't force tox for when we're trying to iterate quickly in a local dev environment.
470bff0 to
53a6af0
Compare
3f87ff4 to
bb4a94a
Compare
Addresses review feedback on openedx#281: - Restore the [isort] settings from master's setup.cfg (dropped when setup.cfg was removed) as [tool.isort] in pyproject.toml. Without it, isort fell back to defaults and collapsed imports into a horizontal grid; re-running isort restores the readable one-per-line format. - Rename the `lint` make target to `quality` for parity with master's `test-quality` and to reflect that it runs more than linting. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Closing on account of #283 |
Moves channel_integrations/ to src/channel_integrations/, 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 pylint/pycodestyle targets in the quality env - Makefile: prefix src/ onto all 5 localization targets (extract, compile, detect_changed, pull, dummy); atlas pull's local destination path updated, remote Transifex identifier left unchanged - test_settings.py: LOCALE_PATHS root() call updated - docs/conf.py: sphinx-apidoc call updated to point at src/channel_integrations - MANIFEST.in: recursive-include path updated Verified: uv sync (no lock drift), full django42 test run (893 passed), quality and pii_check envs pass, uv build --wheel + twine check pass. The docs tox env fails both before and after this change (a pre-existing sphinx/autodoc ValueError in object_description, unrelated to src-layout and unrelated to this repo's file layout) -- confirmed by reproducing the identical failure on the pre-migration commit via git stash.
…e) (#316) * feat: consolidate package metadata into pyproject.toml 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> * feat: switch dependency management from pip-compile to uv 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-lock-runner, update Makefile targets, and switch CI (including the mysql8 migrations check) to install uv and run tests via `uv run tox`. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * feat: add semantic-release for automated PyPI publishing Replace the manual GitHub-release-triggered publish workflow with python-semantic-release: pushes to master with conventional commits now automatically bump the version, tag it, and publish to PyPI. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: correct release tag format and restore pycodestyle ignore list 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. Also restores the ignore=E501,W503,W504 pycodestyle setting that was dropped when setup.cfg was deleted -- without it the quality tox env fails on pre-existing long lines that were previously suppressed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: prevent uv sync from implicitly pulling in the dev group 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. Verified with `uv sync --group ci`. Also adds .venv/ to .gitignore alongside the existing venv/ entry. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: publish to PyPI via OIDC instead of token 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> * fix: pin pypa/gh-action-pypi-publish to a commit SHA @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> * fix: set major_on_zero=false and allow_zero_version=true for consistency 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> * refactor: adopt src-layout, matching openedx/sample-plugin Moves taxonomy/ to src/taxonomy/, 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 pylint/pycodestyle/pydocstyle/isort targets in the quality env - Makefile: prefix src/taxonomy onto the 3 localization targets that cd into the package (compile_translations, detect_changed_source_translations, dummy_translations); compile_translations' relative ../manage.py climb 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/taxonomy - MANIFEST.in: recursive-include path updated Verified: uv sync (no lock drift), full django42 test run (315 passed), quality (pylint/pycodestyle/pydocstyle/isort) and pii-annotations envs pass, docs env passes end to end -- sphinx-apidoc generates real API docs from the new path, uv build --wheel + twine check pass. * fix: pattern-gap audit (uv setup, package=true, coverage, changelog) Same category of fixes farhan flagged on the batch's other reviewed PRs: - ci.yml + mysql8-migrations.yml: add enable-cache/python-version to astral-sh/setup-uv and drop the now-redundant actions/setup-python step - pyproject.toml: add [tool.uv] package = true - Drop CHANGELOG.rst from the dynamic readme file list and delete it -- python-semantic-release + GitHub Releases is the changelog of record. Also removes the now-stale MANIFEST.in include and the docs/changelog.rst page (and its toctree entry). - Migrate .coveragerc into [tool.coverage.run] and delete the old file Verified: uv sync (no lock drift), full django52 test run (315 passed), quality, pii-annotations, and docs envs all pass end to end -- docs env's apidoc + wheel build + twine check confirm the readme/coverage config changes work correctly. * docs: drop stale Version/Changelog checklist items from PR template Both referenced files/processes that no longer exist post-migration: CHANGELOG.rst was deleted (python-semantic-release + GitHub Releases is the changelog of record now), and __version__ in taxonomy/__init__.py is no longer manually bumped (versioning is automated by semantic-release based on conventional commits). Neither is a manual per-PR task anymore. * fix: pattern-gap audit round 2 (django42/52 dependency groups, uv run wrapping, dynamic readme) Cross-checked against review comments/fixes from openedx-ledger#242, edx-enterprise-subsidy-client#222, enterprise-access#1015, and enterprise-subsidy#441. - Add test-django42/test-django52 dependency-groups (each layering a Django version pin on top of the shared test group) and declare [tool.uv].conflicts between them, replacing the old single test group + tox deps= overlay. Update tox.ini's [testenv] to select the group by factor and add the previously-missing django42 job to the CI matrix -- only django52 was actually being exercised in CI before this. - Wrap remaining bare tool invocations in the Makefile (coverage erase, pytest --cov-report html, pytest (test target), diff-cover, i18n_tool, manage.py compilemessages) with `uv run`. Transifex's tx binary is left bare since it's installed via curl, not uv/pip. - Drop the redundant dynamic readme field; keep only version as dynamic. - Regenerate uv.lock for the new dependency groups; verified both py312-django42 and py312-django52 tox environments resolve and run. * fix: correct Makefile recipe indentation (tabs, not spaces) Make requires recipe lines to be indented with a literal tab character. An earlier edit in this migration accidentally used spaces for several targets, breaking 'make selfcheck' and CI. * fix: add codecov project threshold for coverage-scope change The uv/pyproject.toml modernization (openedx/public-engineering#506) switched coverage measurement to [tool.coverage.run], which correctly excludes src/taxonomy/tests/*.py from the package's own coverage report instead of counting those (trivially self-covered) test files toward the reported percentage. That's a one-time drop in the reported baseline (98.91% -> 98.70%, 90 files -> 86 files) caused purely by measurement scope, not a regression: every production file's hit/miss counts are unchanged. Add a documented threshold so codecov/project absorbs this one-time drop while still catching genuine future regressions, matching the same fix applied in sibling modernization PRs (ccx-keys#190, opaque-keys#461, openedx-chem#161). * fix: restore CHANGELOG.rst and re-enable python-semantic-release changelog generation A previous pass deleted CHANGELOG.rst and disabled changelog generation (changelog: "false") in release.yml with no ticket justification -- the changelog is genuinely useful historical documentation and semantic-release can keep it current automatically. Restore CHANGELOG.rst from the commit right before it was deleted, add the insertion-marker line PSR's "update" mode looks for, wire up [tool.semantic_release.changelog] to update the existing RST file in place, and remove changelog: "false" from release.yml. tag_format = "{version}" was already correctly set to match this repo's bare-version tag convention (verified against `git tag --sort=-v:refname`), so it's left unchanged. * docs: remove stale manual tag/PyPI-verification steps from PR template python-semantic-release's release.yml now creates the tag, GitHub release, and publishes to PyPI automatically on merge -- these were no longer real manual steps for a contributor to perform. * fix: use stable pypa publish tag and drop tox from Makefile - pypa/gh-action-pypi-publish: revert the hash-pinned SHA back to the stable @release/v1 tag. A hash-pinned version of this action broke PyPI publishing previously, which is why the org standardized on the stable tag for this specific action. - Makefile: inline the actual sphinx/pylint/pycodestyle/pydocstyle/ isort/code_annotations commands from tox.ini's docs/quality/ pii-annotations envs instead of shelling out to `uv run tox -e ...`, matching the no-tox-in-Makefile convention already used elsewhere (e.g. enterprise-catalog). test-all now depends on quality/pii_check/ test directly. tox.ini itself is untouched; CI's own matrix testing still uses tox directly. * fix: use int-parseable fallback_version instead of 0.0.0.dev0 "0.0.0.dev0" is the exact fallback_version value that crashed 17 tests in a sibling repo (openedx-events) -- runtime code that parses __version__ via tuple(map(int, __version__.split("."))) chokes on the non-numeric "dev0" segment. No current consumer here does that (this repo's own __version__ usage, if any, only interpolates it as a string), but there's no reason to keep a fallback value from the exact banned-pattern class when a plain int-parseable "0.0.0" is equally valid and strictly safer. * fix: pure-uv mysql8-migrations job, remove permanent codecov threshold - mysql8-migrations.yml: replaced uv pip uninstall/install --no-binary (x2) with a single native `uv sync --group mysql8 --no-binary-package mysqlclient --no-binary-package xmlsec`. mysqlclient/xmlsec weren't pulled in by any existing group (confirmed: a plain `uv sync --group dev` installs neither), so added a new `mysql8` dependency-group for them -- this workflow-only need is the same as master's pre-migration behavior, where they came in only via this same job's own pip uninstall+reinstall step, not via requirements/dev.txt or test.txt. Verified the sync+flag combo genuinely triggers source builds for both (confirmed via -v output and a real build attempt, blocked locally only by a missing macOS pkg-config/mysql-dev system dependency that the CI runner's own `apt-get install libxmlsec1-dev` step already covers). - codecov.yml: removed the permanent `threshold: 1%`, per salman2013's question (#316 (comment)) on whether this was meant to be temporary. It wasn't actually needed: this status check isn't required for merging, and `target: auto` compares each PR against its own base commit, so the one-time coverage- scope discontinuity (98.91% -> 98.70%) only ever affected this PR's own diff display -- once merged, 98.70% becomes the new baseline for every future comparison, with no lingering gap for a permanent threshold to paper over. Kept the explanatory comment, dropped the actual tolerance, since a standing 1% regression-masking allowance had no real job to do and only downside. Found while auditing this repo for uv pip usage per the lessons learned on openedx-platform#38915. * fix: disable python-semantic-release changelog generation Set changelog: "false" on the PSR release step and remove the [tool.semantic_release.changelog] config / insertion marker. Checked against openedx/XBlock's actual production release.yml (the one repo in this effort that has cut real automated releases) -- every run passes changelog: false and invokes `semantic-release -v version --no-changelog`, and the repo has zero github-actions[bot] commits ever. The auto-changelog config this migration previously added was only ever verified via a local dry-run prototype, never against a real release. feanil flagged the same issue on openedx/DoneXBlock#388: "I thought we were not going to add changelogs since they can't be updated by python-semantic-release the way we have it setup." * fix: create GitHub release with assets attached, not after publish This repo has immutable releases enabled, which freezes a release's assets the moment it's published. The old flow (main PSR step publishes the release, a separate publish-action step attaches assets afterward) can never work under that constraint -- it would 422 on the first real release. Matches the fix already proven and merged on openedx/sample-plugin#57 and validated end-to-end on openedx/event-tracking#434: build without publishing (vcs_release: false), then create the release with dist/* attached in one gh release create call. * fix: trim verbose codecov.yml comment to match sibling repos Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: pin release.yml actions to sample-plugin's gold-standard SHAs openedx/sample-plugin's release.yml is this org's designated reference for action pins in this migration effort. This repo's release.yml had drifted from it on every pin: - actions/checkout: v7.0.0 (9c091bb2) -> v7.0.1 (3d3c42e5), matching sample-plugin - python-semantic-release: v10.5.3 (350c48fc) -> v10.6.2 (9a026e93) - actions/upload-artifact: v4.6.2 (ea165f8d) -> v7.0.1 (043fb46d) - actions/download-artifact: v4.3.0 (d3f86a10) -> v8.0.1 (3e5f45b2) - pypa/gh-action-pypi-publish: unpinned @release/v1 -> SHA-pinned v1.14.2 (dc37677b) The pypa/gh-action-pypi-publish change reverses earlier guidance on this PR: salman2013 previously asked (review comment #3710602930) for this action to be reverted off a SHA pin back to @release/v1 due to a prior publish issue with the hashed version. That guidance has since been superseded -- the same reviewer, on a sibling repo's PR in this same migration effort, directed matching sample-plugin exactly, which now means SHA-pinning this action like every other one in the file. Every SHA above was independently verified against the GitHub API (commit lookup + tag ref, resolving through the annotated tag object where applicable) before use, per this org's history of fabricated/ swapped SHAs in this exact file. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: restore [4.0.0] entry silently dropped from CHANGELOG.rst by merges salman2013 asked (review comment #3710606973) why old release log entries were being removed; this was previously addressed by restoring CHANGELOG.rst's full history in commit e58b416. But three later merge-from-master commits on this branch (6012451, then 1804d5d) brought in master's tip without carrying over master's own [4.0.0] / "chore: upgrade requirements" changelog entry -- despite there being no textual conflict on this file (the entry existed cleanly on master's side with no competing change on the branch side), the merge results ended up without it, so it was silently lost again. Confirmed via `git diff origin/master -- CHANGELOG.rst` before this fix: the only difference between this branch and current master was the missing [4.0.0] entry. Restored it so the file now matches master exactly, keeping this PR's changelog history complete and consistent with what will already be on master when this merges. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: use v-prefixed tag_format for release tag consistency * fix: update author to Open edX Project convention * fix: restore __version__ dropped during pyproject.toml consolidation 4e45689 removed the hardcoded __version__ = "3.0.0" (correctly, since version is now dynamic via setuptools-scm) but never replaced it with the importlib.metadata equivalent, unlike sibling repos in this migration batch. taxonomy.__version__ has been silently missing since. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: remove dangling codecov.yml comment, not present pre-migration Points at "see PR description" for an explanation -- fragile since the PR description is external and mutable. Coverage config itself stays out of scope for this migration; just dropping the comment, no change to target/threshold behavior. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: use secrets.GITHUB_TOKEN instead of custom org secret for release job Matches openedx/sample-plugin's current release.yml; the custom OPENEDX_SEMANTIC_RELEASE_GITHUB_TOKEN secret isn't needed. * fix: restore tox delegation for docs/quality/pii_check targets Makefile targets were fully inlining commands that tox.ini already defines as standalone envs. pii_check delegates to tox -e pii-annotations, matching the actual tox env name (not pii_check). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: drop uv run from Makefile per feanil's review feedback Makefile now assumes an already-synced/activated local env; uv run stays in CI workflow steps only. See openedx/ccx-keys#190 (review comment r4097501942). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: restore full tox matrix on test-all, correct tag_format comment test-all had drifted to depend only on `test` (a single pytest run), making it identical to `validate` and no longer actually covering py312-django42/py312-django52 like its own help text claims. Restore the bare `tox` call so it runs the full envlist. Also corrected the tag_format comment, which claimed no v-prefixed tag existed -- v4.0.0 already does, same commit as the old bare 4.0.0 tag. Per feanil's review on #316: discussion_r4097760680, r4097760715. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: remove django42 from CI matrix, restore pre-migration scope CI stopped exercising django42 in 2026-02 (3b842b7), keeping it only in tox.ini's envlist for local/manual use; the migration's ci.yml regenerated the matrix from tox.ini and silently reintroduced it as a CI job. Per this effort's policy, a migration PR must not expand CI scope beyond what pre-existed. Coverage step already correctly targets django52, so no other change is needed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix: include doc group in dev group; bump python-semantic-release to v10.7.0 - dev omitted {include-group = "doc"}, so `uv sync --group dev` never provisioned doc8/Sphinx and `make docs` failed on a fresh clone. Matches the pattern already used in openedx/edx-enterprise's pyproject.toml. - Bump python-semantic-release action pin from v10.6.2 to v10.7.0, matching openedx/sample-plugin's current live pin. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Irfan Ahmad <irfan.ahmad@A006-01919.local> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Important
PR implemented with the assistance of Claude Code, human-reviewed and improved before pushing to code review.
Split out of #280; ruff retained there for adoption in a future epic (per public-engineering#506).
Summary
Modernize
forumto uv + pyproject.toml (PEP 621/735) + src/ layout + python-semantic-release.Part of openedx/public-engineering#506.
setup.py/setup.cfgwithpyproject.toml(PEP 621 static metadata)uvwith PEP 735 dependency groups; commituv.locksrc/layoutpyproject.tomltox.inito usetox-uvwithuv-venv-lock-runnerastral-sh/setup-uv; SHA-pin all actions; addworkflow_calltriggerpython-semantic-release+release.yml(OIDC trusted publishing)Removed
Deleted files:
setup.py,setup.cfg,requirements/,.coveragerc,mypy.ini,CHANGELOG.rstRemoved Makefile targets:
clean_toxtox-uv; manual tox cache cleaning no longer neededcompile-requirementsuv+uv.lockpiptoolstest-alltox/ CI matrixtest-qualitylinttarget (uv run tox -e quality)test-lintlinttarget (uv run tox -e quality)test-codestylelinttarget (uv run tox -e quality)test-isortlinttarget (uv run tox -e quality)test-mypymypytarget (uv run tox -e mypy)test-formatblack --check; format checking is no longer a separate CI quality gate; theformattarget now auto-fixesVersioning
[Dynamic]
setuptools-scmwithdynamic = ["version"]— master had a PyPI publish workflow (pypi-publish.yml);python-semantic-releasecontrols the version string at release time via git tags. Repo is on0.x, soallow_zero_version = trueandmajor_on_zero = falseare set to prevent afeat:commit from bumping0.x.y → 1.0.0.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.Code reviewer notes:
openedx/forum, workflowrelease.yml, no environment.commitlint.ymlwas already present on master; this PR does not change it.pyproject.tomldependency groups — verify that all runtime and optional dependencies from the oldrequirements/*.infiles are faithfully carried over, and that no transitive constraint fromrequirements/constraints.txtwas silently dropped.test-format(black --check) was removed as a quality gate; formatting is now only enforced viamake format(auto-fix) rather than CI check — reviewers should verify this is acceptable for this repo.🤖 Generated with Claude Code