Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
cf4e5a4
feat: consolidate package metadata into pyproject.toml
irfanuddinahmad Jul 27, 2026
75af76e
feat: switch dependency management from pip-compile to uv
irfanuddinahmad Jul 27, 2026
a627dec
feat: add semantic-release and commitlint workflows
irfanuddinahmad Jul 27, 2026
8298781
fix: absorb one-time coverage % drop from correcting the test omit pa…
irfanuddinahmad Jul 27, 2026
7d77e2d
refactor: move package to src/ layout
irfanuddinahmad Jul 27, 2026
65c73e5
fix: correct invalid/mismatched action SHA pins in release.yml
irfanuddinahmad Jul 27, 2026
302f909
feat: enable python-semantic-release changelog generation
irfanuddinahmad Jul 30, 2026
7acff25
docs: remove stale scriv changelog checklist item from PR template
irfanuddinahmad Jul 30, 2026
720cf5b
docs: remove stale manual tag/PyPI-verification steps from PR template
irfanuddinahmad Jul 30, 2026
f477922
fix: add myst-parser to doc dependency-group
Aug 11, 2026
07a25b7
fix: disable python-semantic-release changelog generation
Aug 19, 2026
9fb51f6
style: trim codecov.yml explanatory comment
Aug 20, 2026
f904559
fix: drop tox from Makefile's docs target
Aug 24, 2026
b72d6b0
fix: create GitHub release with assets attached, not after publish
irfanuddinahmad Aug 27, 2026
97e8cc7
fix: re-pin release.yml actions to sample-plugin's verified SHAs
irfanuddinahmad Sep 2, 2026
998e0e9
fix: drop unneeded fetch-depth: 0 from ci.yml checkout
irfanuddinahmad Sep 2, 2026
1ee0611
fix: remove unnecessary try/except around __version__ (not present pr…
irfanuddinahmad Sep 9, 2026
fde09f1
fix: remove fail-fast: false (not present pre-migration)
irfanuddinahmad Sep 9, 2026
fd44831
fix: resolve conflicts with main, add SupportContactContextRequested …
irfanuddinahmad Sep 10, 2026
36da1eb
Merge remote-tracking branch 'origin/main' into irfanuddinahmad/moder…
irfanuddinahmad Sep 10, 2026
be2e8a4
fix: remove dangling codecov.yml comment, not present pre-migration
irfanuddinahmad Sep 10, 2026
99ed52e
fix: ignore .venv, missed when this repo moved to uv
irfanuddinahmad Sep 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions .coveragerc

This file was deleted.

3 changes: 0 additions & 3 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,12 @@ Check off if complete *or* not applicable:
- [ ] All reviewers approved
- [ ] Reviewer tested the code following the testing instructions
- [ ] CI build is green
- [ ] Changelog entry added using scriv with short description of the change
- [ ] Documentation updated (not only docstrings)
- [ ] Code dependencies reviewed
- [ ] Fixup commits are squashed away
- [ ] Unit tests added/updated
- [ ] Noted any: Concerns, dependencies, migration issues, deadlines, tickets

**Post Merge:**
- [ ] Trigger the release workflow to create a new GitHub release.
- [ ] Check new version is pushed to PyPI after tag-triggered build is finished.
- [ ] Delete working branch (if not needed anymore)
- [ ] Upgrade the package in the Open edX platform requirements (if applicable)
30 changes: 17 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
name: Python CI

on:
push:
branches: [main]
workflow_call:
pull_request:
branches:
- '**'


jobs:
run_tests:
name: tests
name: ${{ matrix.toxenv }}
runs-on: ${{ matrix.os }}
permissions:
contents: read
strategy:
matrix:
os: [ubuntu-latest]
Expand All @@ -28,21 +29,24 @@ jobs:

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0

- name: Install uv
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
enable-cache: true
python-version: ${{ matrix.python-version }}
# Pinned to match the `uv` package version locked in uv.lock (a
# transitive dependency of tox-uv/tox-uv-bare). Keep this in sync
# whenever `make upgrade` changes that pinned version, otherwise
# tox-uv's internal `--locked` check can disagree with this
# workflow's own `uv sync`/`uv run` calls.
version: "0.11.32"

- name: Install pip
run: pip install -r requirements/pip.txt

- name: Install Dependencies
run: pip install -r requirements/ci.txt
- name: Install CI dependencies
run: uv sync --group ci

- name: Run Tests
env:
TOXENV: ${{ matrix.toxenv }}
run: tox
run: uv run tox -e ${{ matrix.toxenv }}

- name: Run coverage
if: matrix.python-version == '3.12' && matrix.toxenv == 'django42'
Expand Down
30 changes: 0 additions & 30 deletions .github/workflows/pypi-publish.yml

This file was deleted.

136 changes: 81 additions & 55 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,63 +1,89 @@
name: Create a new GitHub Release
name: Release

on:
workflow_dispatch:
inputs:
tag:
description: "The type of version bump"
required: true
type: choice
options:
- "major"
- "minor"
- "patch"
push:
branches: [main]

jobs:
run_tests:
uses: ./.github/workflows/ci.yml
secrets: inherit
permissions:
contents: read

release:
runs-on: ubuntu-latest
env:
TAG: ${{ github.event.inputs.tag }}
needs: run_tests
if: github.ref_name == 'main'
concurrency:
group: ${{ github.workflow }}-release-${{ github.ref_name }}
cancel-in-progress: false
permissions:
contents: write
outputs:
released: ${{ steps.release.outputs.released || 'false' }}
version: ${{ steps.release.outputs.version }}

steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ github.ref_name }}

- run: git reset --hard ${{ github.sha }}

- name: Python Semantic Release
id: release
uses: python-semantic-release/python-semantic-release@9a026e9303981c866c3425723009becb2437c757 # v10.6.2
with:
github_token: ${{ secrets.OPENEDX_SEMANTIC_RELEASE_GITHUB_TOKEN }}
git_committer_name: "github-actions"
git_committer_email: "github-actions@github.com"
changelog: "false"
# Commit, tag, push and build, but don't create the GitHub release.
# We create it ourselves in the next step so that the distributions
# are attached before the release is published. See that step for why.
vcs_release: "false"

# This repo has immutable releases enabled, which freezes a release's
# assets the moment it is published, so assets cannot be attached
# afterwards. `gh release create` handles this by creating the release as
# a draft, uploading the assets, and only then publishing it:
# https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/immutable-releases
- name: Publish | Create GitHub Release with Assets
if: steps.release.outputs.released == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_NOTES: ${{ steps.release.outputs.release_notes }}
TAG: ${{ steps.release.outputs.tag }}
run: |
printf '%s' "$RELEASE_NOTES" > "$RUNNER_TEMP/release_notes.md"
gh release create "$TAG" \
--verify-tag \
--title "$TAG" \
--notes-file "$RUNNER_TEMP/release_notes.md" \
dist/*

- name: Upload dist artifacts
if: steps.release.outputs.released == 'true'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: dist
path: dist/
if-no-files-found: error

publish_to_pypi:
runs-on: ubuntu-latest
needs: release
if: github.ref_name == 'main' && needs.release.outputs.released == 'true'
permissions:
id-token: write

steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: 3.12

- name: Install requirements
run: pip install scriv bump-my-version

- name: Install pandoc for scriv
run: sudo apt install -y pandoc

- name: Set up Git
run: |
git config user.name 'github-actions[bot]'
git config user.email 'github-actions[bot]@users.noreply.github.com'

- name: Get current and new version
id: version
run: |
echo "CURRENT_VERSION=$(bump-my-version show current_version)" >> $GITHUB_OUTPUT
echo "NEW_VERSION=$(bump-my-version show --increment $TAG new_version)" >> $GITHUB_OUTPUT

- name: Bump version
run: bump-my-version bump $TAG

- name: Collect changelog
run: make changelog

- name: Commit changes and create tag
uses: stefanzweifel/git-auto-commit-action@4a55954c782fc1ea30b9056cd3e7a2b40ca8887d # v7.2.0
with:
branch: ${{ github.ref }}
commit_message: "chore: bump version ${{ steps.version.outputs.CURRENT_VERSION }} → ${{ steps.version.outputs.NEW_VERSION }}"
tagging_message: "v${{ steps.version.outputs.NEW_VERSION }}"

- name: Create GitHub release
run: scriv github-release --repo=openedx/openedx-filters
env:
GITHUB_TOKEN: ${{ github.token }}
- name: Download dist artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: dist
path: dist/

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
__pycache__
.pytest_cache

# uv virtual environment
.venv

# C extensions
*.so

Expand Down
5 changes: 4 additions & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ sphinx:

python:
install:
- requirements: requirements/doc.txt
- method: uv
command: sync
groups:
- doc
6 changes: 2 additions & 4 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
include CHANGELOG.rst
include LICENSE.txt
include README.rst
include requirements/base.in
recursive-include openedx_filters *.html *.png *.gif *.js *.css *.jpg *.jpeg *.svg *.py
include openedx_filters/py.typed
include requirements/constraints.txt
recursive-include src/openedx_filters *.html *.png *.gif *.js *.css *.jpg *.jpeg *.svg *.py
include src/openedx_filters/py.typed
49 changes: 16 additions & 33 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ coverage: clean ## generate and view HTML coverage report
$(BROWSER)htmlcov/index.html

docs: ## generate Sphinx HTML documentation, including API docs
tox -e docs
uv sync --group doc
DJANGO_SETTINGS_MODULE=test_utils.test_settings PYTHONPATH=$(CURDIR) uv run doc8 --ignore-path docs/_build README.rst docs
rm -f docs/openedx_filters.rst
rm -f docs/modules.rst
DJANGO_SETTINGS_MODULE=test_utils.test_settings PYTHONPATH=$(CURDIR) uv run make -C docs clean
DJANGO_SETTINGS_MODULE=test_utils.test_settings PYTHONPATH=$(CURDIR) uv run make -C docs html
$(BROWSER)docs/_build/html/index.html

changelog-entry: ## Create a new changelog entry
Expand All @@ -36,45 +41,23 @@ changelog-entry: ## Create a new changelog entry
changelog: ## Collect changelog entries in the CHANGELOG.rst file
scriv collect

# Define PIP_COMPILE_OPTS=-v to get more information during make upgrade.
PIP_COMPILE = pip-compile --upgrade $(PIP_COMPILE_OPTS)

upgrade: export CUSTOM_COMPILE_COMMAND=make upgrade
upgrade: ## update the requirements/*.txt files with the latest packages satisfying requirements/*.in
pip install -qr requirements/pip-tools.txt
pip install -qr requirements/pip.txt
# Make sure to compile files after any other files they include!
$(PIP_COMPILE) --allow-unsafe --rebuild -o requirements/pip.txt requirements/pip.in
$(PIP_COMPILE) -o requirements/pip-tools.txt requirements/pip-tools.in
pip install -qr requirements/pip.txt
pip install -qr requirements/pip-tools.txt
$(PIP_COMPILE) -o requirements/base.txt requirements/base.in
$(PIP_COMPILE) -o requirements/test.txt requirements/test.in
$(PIP_COMPILE) -o requirements/doc.txt requirements/doc.in
$(PIP_COMPILE) -o requirements/quality.txt requirements/quality.in
$(PIP_COMPILE) -o requirements/ci.txt requirements/ci.in
$(PIP_COMPILE) -o requirements/dev.txt requirements/dev.in

# Let tox control the Django version for tests
sed -i.tmp '/^[d|D]jango==/d' requirements/test.txt
sed -i.tmp '/^djangorestframework==/d' requirements/test.txt
rm requirements/test.txt.tmp
upgrade: ## update the uv.lock file with the latest packages satisfying pyproject.toml
uv run --with edx-lint edx_lint write_uv_constraints pyproject.toml
uv lock --upgrade

quality: ## check coding style with pycodestyle and pylint
pylint openedx_filters test_utils *.py
pylint src/openedx_filters test_utils *.py
mypy
pycodestyle openedx_filters *.py
ruff check openedx_filters *.py
isort --check-only --diff test_utils openedx_filters *.py
python setup.py bdist_wheel
pycodestyle src/openedx_filters *.py
ruff check src/openedx_filters *.py
isort --check-only --diff test_utils src/openedx_filters *.py
python -m build --wheel
twine check dist/*
make selfcheck


requirements: ## install development environment requirements
pip install -r requirements/pip.txt
pip install -r requirements/pip-tools.txt
pip-sync requirements/dev.txt requirements/private.*
uv sync --group dev

test: clean ## run tests in the current virtualenv
pytest
Expand All @@ -83,7 +66,7 @@ diff_cover: test ## find diff lines that need test coverage
diff-cover coverage.xml

test-all: quality ## run tests on every supported Python/Django combination
tox
uv run tox

validate: quality test ## run tests and quality checks

Expand Down
1 change: 0 additions & 1 deletion changelog.d/scriv.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
[scriv]
version = literal: openedx_filters/__init__.py: __version__
format = rst
entry_title_template = file: changelog.d/scriv/entry_title.${config:format}.j2
new_fragment_template = file: changelog.d/scriv/new_fragment.${config:format}.j2
Expand Down
7 changes: 5 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import sys
from os.path import dirname, relpath

sys.path.insert(0, os.path.abspath('..'))
sys.path.insert(0, os.path.abspath('../src'))

# -- Project information -----------------------------------------------------

Expand Down Expand Up @@ -218,7 +218,10 @@ def linkcode_resolve(domain: str, info: dict[str, str]) -> str | None:

import openedx_filters

start_dir = os.path.abspath(os.path.join(dirname(openedx_filters.__file__), ".."))
# openedx_filters.__file__ is src/openedx_filters/__init__.py under the
# src/ layout, so go up two levels (out of src/) to reach the repo root
# that GitHub blob URLs are relative to.
start_dir = os.path.abspath(os.path.join(dirname(openedx_filters.__file__), "..", ".."))
file_path = relpath(file_path, start=start_dir).replace(os.path.sep, "/")

return f"{REPO_URL}/{file_path}{linespec}"
Loading