Repository navigation
chore: modernize Python tooling (uv, PEP 621, semantic-release, src layout) - #265
salman2013 wants to merge 3 commits into
Conversation
|
Thanks for the pull request, @salman2013! This repository is currently maintained by 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 approvalIf you haven't already, check this list to see if your contribution needs to go through the product review process.
🔘 Provide contextTo 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:
🔘 Get a green buildIf one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green. DetailsWhere 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:
💡 As a result it may take up to several weeks or months to complete a review and merge your PR. |
| from .image_explorer import ImageExplorerBlock | ||
|
|
||
| __version__ = '3.1.1' | ||
| __version__ = version("xblock-image-explorer") |
There was a problem hiding this comment.
__version__ is assigned without a fallback. If the package is not installed, importlib.metadata.version() raises PackageNotFoundError and the import of this module fails entirely. Either:
- Add a
try/except PackageNotFoundErrorguard with a__version__ = "0.0.0"fallback, or - Remove
__version__entirely if no downstream code imports it (the simpler outcome).
There was a problem hiding this comment.
fixed and remove version entirely if no downstream code imports it (the simpler outcome).
| @@ -0,0 +1,140 @@ | |||
| [build-system] | |||
| requires = ["setuptools>=64", "setuptools-scm>=8.0"] | |||
There was a problem hiding this comment.
We discussed about it before.
Should we add the minimum bound in setuptools>=64
| "static/**", | ||
| "templates/**", | ||
| "public/**", | ||
| "conf/locale/**", |
There was a problem hiding this comment.
translations/config.yaml is present in the repo (src/image_explorer/translations/) and was included in the master wheel, but is missing from the PR wheel. Add "translations/**" to [tool.setuptools.package-data]:
[tool.setuptools.package-data]
"image_explorer" = [
"static/**",
"templates/**",
"public/**",
"conf/locale/**",
"translations/**",
]There was a problem hiding this comment.
Because translations/ in this repo is a symlink (git mode 120000) pointing to conf/locale/. Setuptools cannot copy symlinks as package data — it fails with:
error: can't copy 'src/image_explorer/translations': doesn't exist or not a regular file
The actual files (like config.yaml) live in conf/locale/, which is already covered by the existing "conf/locale/" entry. So adding "translations/" would be redundant and break the wheel build.
There was a problem hiding this comment.
Just reviewed the translations setup — translations/config.yaml is the atlas config used to pull translation files into the source repo (via make pull_translations in the Makefile). Atlas reads the source tree, not the installed wheel, so this file doesn't need to be in the package. Closing this comment.
https://github.com/salman2013/xblock-image-explorer/blob/modernize-python-tooling/src/image_explorer/conf/locale/config.yaml
https://github.com/salman2013/xblock-image-explorer/blob/modernize-python-tooling/Makefile
| name: Python CI | ||
|
|
||
| on: | ||
| push: |
There was a problem hiding this comment.
Is this removal intentional?
@claude generated details:
Thepush: branches: [master]trigger was removed. Master CI used it to run checks on direct pushes to master; with onlyworkflow_calladded, direct pushes no longer trigger CI independently. Consider restoring thepush:trigger alongsideworkflow_call:.
|
|
||
| - name: Upload dist artifacts | ||
| if: steps.release.outputs.released == 'true' | ||
| uses: actions/upload-artifact@v4 |
There was a problem hiding this comment.
actions/upload-artifact@v4 uses a mutable tag. All other actions in this PR are SHA-pinned — pin this one too.
Resolve the current SHA:
gh api repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha|
|
||
| steps: | ||
| - name: Download dist artifacts | ||
| uses: actions/download-artifact@v4 |
There was a problem hiding this comment.
same:
actions/download-artifact@v4 uses a mutable tag. Pin to a full SHA with a version comment, matching the pattern used for the other actions in this workflow.
| $(PIP_COMPILE) -o requirements/ci.txt requirements/ci.in | ||
| sed -i '/^[dD]jango==/d' requirements/test.txt | ||
| upgrade: ## update uv.lock and constraints with the latest packages | ||
| uv lock --upgrade |
There was a problem hiding this comment.
The upgrade target runs uv lock --upgrade before edx_lint write_uv_constraints. The standard order is edx_lint write_uv_constraints first (so constraints are updated), then uv lock --upgrade (so the lockfile respects them). Swap the two lines.
| [tool.semantic_release] | ||
| # version is dynamic via setuptools-scm; no version_toml needed | ||
| build_command = "python -m pip install --upgrade build && SETUPTOOLS_SCM_PRETEND_VERSION=$NEW_VERSION python -m build" | ||
| allow_zero_version = true |
There was a problem hiding this comment.
I think repo already has version greater than zero, removing this config will be a great cleanup.
| {group = "django42"}, | ||
| ], | ||
| ] | ||
| constraint-dependencies = [] |
There was a problem hiding this comment.
The next line (constraint-dependencies = []) is empty — edx_lint write_uv_constraints was never run.
Without this, global edx-lint constraints (security pins, compatibility caps) are not applied to the lockfile. Run:
uv run --with edx-lint edx_lint write_uv_constraints pyproject.toml
Then commit the updated pyproject.toml and uv.lock.
| commands = | ||
| mkdir -p var | ||
| pytest {posargs:tests --cov image_explorer} | ||
|
|
There was a problem hiding this comment.
pytest is called directly here. Per the tooling flow, the Makefile should define commands and tox should call them:
- Add to
Makefile:test: ## run tests mkdir -p var pytest $(posargs)
- Change this
commandsline tomake test.
| commands = | ||
| pylint --fail-under=9.0 image_explorer | ||
| pylint --fail-under=9.0 src/image_explorer | ||
|
|
There was a problem hiding this comment.
pylint is called directly here. Per the tooling flow, the Makefile should define commands and tox should call them:
- Add to
Makefile:quality: ## run linting pylint --fail-under=9.0 src/image_explorer
- Change this
commandsline tomake quality.
| path: dist/ | ||
|
|
||
| - name: Publish to PyPI | ||
| uses: pypa/gh-action-pypi-publish@release/v1 |
There was a problem hiding this comment.
The uses: on the next line (pypa/gh-action-pypi-publish@release/v1) is not SHA-pinned — all other actions in this PR use a full commit SHA. Pin it:
uses: pypa/gh-action-pypi-publish@<SHA> # release/v1Get the current SHA:
gh api repos/pypa/gh-action-pypi-publish/git/ref/heads/release/v1 --jq '.object.sha'
|
Hi @salman2013! Some branch conflicts have popped up - would you mind taking a look? |
|
Hi @salman2013, it seems like this PR could benefit from the changes applied to other repos as part of their modernization. I'm converting this to a draft; please mark it as "ready for review" once it's ready. |
f7ae64d to
88e0e8d
Compare
- Migrate package metadata from setup.py/setup.cfg to pyproject.toml (PEP 621) - Switch dependency management from pip-tools to uv with dependency groups - Migrate to src/ layout - Add python-semantic-release and commitlint workflows - Replace pypi-publish.yml with release.yml (PSR + OIDC trusted publisher) - Add uv.lock and drop requirements/ directory Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
88e0e8d to
b54d7cd
Compare
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| @@ -1,29 +1,32 @@ | |||
| [tox] | |||
| envlist = py312-django{42,52},quality,package | |||
There was a problem hiding this comment.
docs was not in the original tox.ini on master before the migration.
| requirements: piptools ## install test requirements locally | ||
| pip-sync requirements/ci.txt | ||
| quality: ## run linting | ||
| pylint --fail-under=9.0 src/image_explorer |
| pip install -r requirements/pip-tools.txt | ||
| test: ## run tests | ||
| mkdir -p var | ||
| pytest $(posargs) |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Summary
pyproject.toml(PEP 621) — removedsetup.py, addedsetuptools-scmfor dynamic versioning, coverage config,importlib.metadatafor__version__pip-tools/requirements/*.txttouv+uv.lockwith[dependency-groups]; updatetox.inito usetox-uv/uv-venv-lock-runner; update CI to useastral-sh/setup-uvpython-semantic-releaseworkflow for automated PyPI publishing via OIDC trusted publisher; addcommitlintworkflow to enforce conventional commitssrc/layout — movedimage_explorer/tosrc/image_explorer/Test plan
uv run tox -e quality— pylint 9.45/10, passesuv run tox -e py312-django42— 6/6 tests passeduv run tox -e py312-django52— 6/6 tests passedopenedx/xblock-image-explorer(publisher: GitHub Actions, workflow:release.yml)🤖 Generated with Claude Code