diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e0231189..20435fbf 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -55,8 +55,7 @@ Check off if complete *or* not applicable: - [ ] All reviewers approved - [ ] Reviewer tested the code following the testing instructions - [ ] CI build is green -- [ ] Version bumped -- [ ] Changelog record added with short description of the change and current date +- [ ] Changelog entry added using scriv with short description of the change - [ ] Documentation updated (not only docstrings) - [ ] Integration with other services reviewed - [ ] Fixup commits are squashed away @@ -64,9 +63,7 @@ Check off if complete *or* not applicable: - [ ] Noted any: Concerns, dependencies, migration issues, deadlines, tickets **Post Merge:** -- [ ] Create a tag -- [ ] Create a release on GitHub -- [ ] Check new version is pushed to PyPI after tag-triggered build is - finished. +- [ ] 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) diff --git a/.github/workflows/create-release-pr.yml b/.github/workflows/create-release-pr.yml new file mode 100644 index 00000000..51cd03f2 --- /dev/null +++ b/.github/workflows/create-release-pr.yml @@ -0,0 +1,61 @@ +name: Create a Release Pull Request + +on: + workflow_dispatch: + inputs: + bump-type: + description: "The type of version bump" + required: true + type: choice + options: + - "major" + - "minor" + - "patch" + +jobs: + create-release-pr: + runs-on: ubuntu-latest + env: + BUMP_TYPE: ${{ github.event.inputs.bump-type }} + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.11 + + - name: Install release requirements + run: pip install scriv bump-my-version + + - name: Configure Git user + run: | + git config user.name 'github-actions[bot]' + git config user.email 'github-actions[bot]@users.noreply.github.com' + + - name: Compute version bump + id: version + run: | + echo "CURRENT_VERSION=$(bump-my-version show current_version)" >> $GITHUB_OUTPUT + echo "NEW_VERSION=$(bump-my-version show --increment $BUMP_TYPE new_version)" >> $GITHUB_OUTPUT + + - name: Bump version + run: bump-my-version bump $BUMP_TYPE + + - name: Collect changelog + run: make changelog + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v7 + with: + commit-message: "chore: bump version ${{ steps.version.outputs.CURRENT_VERSION }} → ${{ steps.version.outputs.NEW_VERSION }}" + title: "v${{ steps.version.outputs.NEW_VERSION }} Release" + body: | + ### Description + + This PR bumps the version from `${{ steps.version.outputs.CURRENT_VERSION }}` to `${{ steps.version.outputs.NEW_VERSION }}`. + + The changelog has been automatically generated using `scriv`. + branch: "release-${{ steps.version.outputs.NEW_VERSION }}" diff --git a/.github/workflows/github-release.yml b/.github/workflows/github-release.yml new file mode 100644 index 00000000..424476ff --- /dev/null +++ b/.github/workflows/github-release.yml @@ -0,0 +1,45 @@ +name: Create a new GitHub Release + +on: + workflow_dispatch: + +jobs: + github-release: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.11 + + - name: Install release requirements + run: pip install scriv bump-my-version + + - name: Install pandoc for scriv + run: sudo apt install -y pandoc + + - name: Configure Git user + run: | + git config user.name 'github-actions[bot]' + git config user.email 'github-actions[bot]@users.noreply.github.com' + + - name: Read current version + id: version + run: | + echo "CURRENT_VERSION=$(bump-my-version show current_version)" >> $GITHUB_OUTPUT + + - name: Create and push Git tag + env: + CURRENT_VERSION: ${{ steps.version.outputs.CURRENT_VERSION }} + run: | + git tag -a "v$CURRENT_VERSION" -m "Release v$CURRENT_VERSION" + git push origin "v$CURRENT_VERSION" + + - name: Create GitHub release + run: scriv github-release --repo=openedx/openedx-events + env: + GITHUB_TOKEN: ${{ github.token }} diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 0552e620..f7ea4db4 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,7 +3,7 @@ Change Log .. All enhancements and patches to openedx_events will be documented - in this file. It adheres to the structure of https://keepachangelog.com/ , + in this file. It adheres to the structure of https://keepachangelog.com/, but in reStructuredText instead of Markdown (for ease of incorporation into Sphinx documentation and the PyPI description). @@ -11,11 +11,33 @@ Change Log .. There should always be an "Unreleased" section for changes pending release. +.. + ⚠️ PLEASE, DO NOT ADD YOUR CHANGES TO THIS FILE! (unless you want to modify + existing changelog entries in this file) Changelog entries are managed by + scriv. + + If you need to add a changelog entry: + + - Run `make changelog-entry` to create a new changelog entry. + - Edit and commit the newly-created file in the `changelog.d` folder + following the instructions in the file. + If you need to create a new release: + + - There is a `relese.yml` workflow to create a new release. You can trigger + it manually in the Actions tab in GitHub. The workflow will bump the + version, update the changelog, create a tag, and create a new GitHub + release! 🚀 Unreleased __________ +See the fragment files in the `changelog.d directory`_. + +.. _changelog.d directory: https://github.com/openedx/openedx-events/tree/master/changelog.d + +.. scriv-insert-here + [10.5.0] - 2025-08-19 --------------------- @@ -33,7 +55,6 @@ Added * Added new ``ENTERPRISE_GROUP_DELETED`` event in enterprise. - [10.3.0] - 2025-05-23 --------------------- @@ -76,10 +97,13 @@ Added * Added new ``EXTERNAL_GRADER_SCORE_SUBMITTED`` event in learning. * Add ``ExternalGraderScoreData`` to support this event + [10.0.0] - 2024-04-04 --------------------- + Changed ~~~~~~~ + * **Breaking change**: LibraryCollectionData now takes only a LibraryCollectionLocator. * **Breaking change**: LibraryContainerData now takes only a LibraryContainerLocator. diff --git a/Makefile b/Makefile index af1991aa..7fcd1013 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ .PHONY: clean clean_tox compile_translations coverage diff_cover docs dummy_translations \ extract_translations fake_translations help pull_translations push_translations \ - quality requirements selfcheck test test-all upgrade validate install_transifex_client + quality requirements selfcheck test test-all upgrade validate install_transifex_client \ + changelog-entry changelog .DEFAULT_GOAL := help @@ -32,6 +33,12 @@ docs: ## generate Sphinx HTML documentation, including API docs tox -e docs $(BROWSER)docs/_build/html/index.html +changelog-entry: ## Create a new changelog entry + scriv create + +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) diff --git a/changelog.d/20250929_221720_bryann.valderrama_scriv.rst b/changelog.d/20250929_221720_bryann.valderrama_scriv.rst new file mode 100644 index 00000000..19382f61 --- /dev/null +++ b/changelog.d/20250929_221720_bryann.valderrama_scriv.rst @@ -0,0 +1,3 @@ +Added +~~~~~ +* Migrate to scriv to manage changelog. (by @bryanttv in #472) diff --git a/changelog.d/scriv.ini b/changelog.d/scriv.ini new file mode 100644 index 00000000..57a747bc --- /dev/null +++ b/changelog.d/scriv.ini @@ -0,0 +1,6 @@ +[scriv] +version = literal: openedx_events/__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 +rst_header_chars = -~ diff --git a/changelog.d/scriv/entry_title.rst.j2 b/changelog.d/scriv/entry_title.rst.j2 new file mode 100644 index 00000000..fd75491e --- /dev/null +++ b/changelog.d/scriv/entry_title.rst.j2 @@ -0,0 +1 @@ +{% if version %}[v{{ version }}] - {% endif %}{{ date.strftime('%Y-%m-%d') }} diff --git a/changelog.d/scriv/new_fragment.rst.j2 b/changelog.d/scriv/new_fragment.rst.j2 new file mode 100644 index 00000000..c13f3205 --- /dev/null +++ b/changelog.d/scriv/new_fragment.rst.j2 @@ -0,0 +1,44 @@ +.. Create a new changelog entry for every new user-facing change. + +.. Please respect the following instructions: +.. * Add a new bullet item for the category that best describes the change. +.. * You may optionally append "(by @ in #)" at the end of +.. the bullet item. This will be used to credit the PR author in the bullet +.. item, where is the GitHub username of the author of the change +.. and is the PR number of the change. These affiliations will +.. be displayed in the release notes for every release. +.. * The accepted categories are: Added, Changed, Deprecated, Removed, Fixed, +.. and Security. +.. * Indicate breaking changes with a "**BREAKING CHANGE:**" prefix in the +.. bullet item. + +.. For example: + +.. Added +.. ~~~~~ +.. * Added new ``COURSE_DOWNLOADED_COMPLETED`` event. +.. * Added support for annotated Python dictionaries as Avro Map type. (by @developer in #1) + +.. Changed +.. ~~~~~~~ +.. * Added support for Python 3.12. +.. * **BREAKING CHANGE:** Updated from Django 3.x to 4.x. (by @developer #2) + +.. Deprecated +.. ~~~~~~~~~~ +.. * Deprecated ``COURSE_DOWNLOADED_STARTED`` event +.. * Deprecated use of non-annotated dictionaries in events. (by @developer #3) + +.. Removed +.. ~~~~~~~ +.. * Removed support for Python 3.8. +.. * Removed unused ``COURSE_DOWNLOADED_STARTED`` event. (by @developer #4) + +.. Fixed +.. ~~~~~ +.. * Fixed event validation in background processes. +.. * Fixed incorrect handling of event payloads. (by @developer #4) + +.. Security +.. ~~~~~~~~ +.. * Updated dependencies to patch security vulnerabilities. diff --git a/requirements/base.txt b/requirements/base.txt index 0c58a234..f6a52a8d 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -4,13 +4,13 @@ # # make upgrade # -asgiref==3.9.1 +asgiref==3.9.2 # via django attrs==25.3.0 # via -r requirements/base.in cffi==2.0.0 # via pynacl -click==8.2.1 +click==8.3.0 # via edx-django-utils django==4.2.24 # via @@ -27,7 +27,7 @@ dnspython==2.8.0 # via pymongo edx-ccx-keys==2.0.2 # via -r requirements/base.in -edx-django-utils==8.0.0 +edx-django-utils==8.0.1 # via -r requirements/base.in edx-opaque-keys[django]==3.0.0 # via @@ -35,11 +35,11 @@ edx-opaque-keys[django]==3.0.0 # edx-ccx-keys fastavro==1.12.0 # via -r requirements/base.in -psutil==7.0.0 +psutil==7.1.0 # via edx-django-utils pycparser==2.23 # via cffi -pymongo==4.15.0 +pymongo==4.15.1 # via edx-opaque-keys pynacl==1.6.0 # via edx-django-utils diff --git a/requirements/dev.in b/requirements/dev.in index 3e059845..4c73e330 100644 --- a/requirements/dev.in +++ b/requirements/dev.in @@ -6,3 +6,4 @@ -r ci.txt # dependencies needed to setup testing environment on CI diff-cover # Changeset diff test coverage +scriv # Changelog management tool diff --git a/requirements/dev.txt b/requirements/dev.txt index eb9b1f3e..0a29c91e 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -4,7 +4,7 @@ # # make upgrade # -asgiref==3.9.1 +asgiref==3.9.2 # via # -r requirements/quality.txt # django @@ -14,7 +14,9 @@ astroid==3.3.11 # pylint # pylint-celery attrs==25.3.0 - # via -r requirements/quality.txt + # via + # -r requirements/quality.txt + # scriv backports-tarfile==1.2.0 # via # -r requirements/quality.txt @@ -45,7 +47,7 @@ charset-normalizer==3.4.3 # via # -r requirements/quality.txt # requests -click==8.2.1 +click==8.3.0 # via # -r requirements/pip-tools.txt # -r requirements/quality.txt @@ -54,10 +56,12 @@ click==8.2.1 # edx-django-utils # edx-lint # pip-tools + # scriv click-log==0.4.0 # via # -r requirements/quality.txt # edx-lint + # scriv code-annotations==2.3.0 # via # -r requirements/quality.txt @@ -66,17 +70,17 @@ colorama==0.4.6 # via # -r requirements/ci.txt # tox -coverage[toml]==7.10.6 +coverage[toml]==7.10.7 # via # -r requirements/quality.txt # pytest-cov -cryptography==45.0.7 +cryptography==46.0.1 # via # -r requirements/quality.txt # secretstorage ddt==1.7.2 # via -r requirements/quality.txt -diff-cover==9.6.0 +diff-cover==9.7.1 # via -r requirements/dev.in dill==0.4.0 # via @@ -105,13 +109,13 @@ dnspython==2.8.0 # via # -r requirements/quality.txt # pymongo -docutils==0.22 +docutils==0.22.2 # via # -r requirements/quality.txt # readme-renderer edx-ccx-keys==2.0.2 # via -r requirements/quality.txt -edx-django-utils==8.0.0 +edx-django-utils==8.0.1 # via -r requirements/quality.txt edx-lint==5.6.0 # via -r requirements/quality.txt @@ -168,6 +172,7 @@ jinja2==3.1.6 # -r requirements/quality.txt # code-annotations # diff-cover + # scriv keyring==25.6.0 # via # -r requirements/quality.txt @@ -176,7 +181,8 @@ markdown-it-py==4.0.0 # via # -r requirements/quality.txt # rich -markupsafe==3.0.2 + # scriv +markupsafe==3.0.3 # via # -r requirements/quality.txt # jinja2 @@ -224,7 +230,7 @@ pluggy==1.6.0 # pytest # pytest-cov # tox -psutil==7.0.0 +psutil==7.1.0 # via # -r requirements/quality.txt # edx-django-utils @@ -261,7 +267,7 @@ pylint-plugin-utils==0.9.0 # -r requirements/quality.txt # pylint-celery # pylint-django -pymongo==4.15.0 +pymongo==4.15.1 # via # -r requirements/quality.txt # edx-opaque-keys @@ -291,7 +297,7 @@ python-slugify==8.0.4 # via # -r requirements/quality.txt # code-annotations -pyyaml==6.0.2 +pyyaml==6.0.3 # via # -r requirements/quality.txt # code-annotations @@ -304,6 +310,7 @@ requests==2.32.5 # -r requirements/quality.txt # id # requests-toolbelt + # scriv # twine requests-toolbelt==1.0.0 # via @@ -317,8 +324,10 @@ rich==14.1.0 # via # -r requirements/quality.txt # twine -ruff==0.13.0 +ruff==0.13.2 # via -r requirements/quality.txt +scriv==1.7.0 + # via -r requirements/dev.in secretstorage==3.4.0 # via # -r requirements/quality.txt diff --git a/requirements/doc.txt b/requirements/doc.txt index 6f3dde12..8e06e483 100644 --- a/requirements/doc.txt +++ b/requirements/doc.txt @@ -8,11 +8,11 @@ accessible-pygments==0.0.5 # via pydata-sphinx-theme alabaster==1.0.0 # via sphinx -anyio==4.10.0 +anyio==4.11.0 # via # starlette # watchfiles -asgiref==3.9.1 +asgiref==3.9.2 # via # -r requirements/test.txt # django @@ -24,7 +24,7 @@ babel==2.17.0 # sphinx backports-tarfile==1.2.0 # via jaraco-context -beautifulsoup4==4.13.5 +beautifulsoup4==4.14.2 # via pydata-sphinx-theme build==1.3.0 # via -r requirements/doc.in @@ -37,7 +37,7 @@ cffi==2.0.0 # pynacl charset-normalizer==3.4.3 # via requests -click==8.2.1 +click==8.3.0 # via # -r requirements/test.txt # code-annotations @@ -47,11 +47,11 @@ code-annotations==2.3.0 # via -r requirements/test.txt colorama==0.4.6 # via sphinx-autobuild -coverage[toml]==7.10.6 +coverage[toml]==7.10.7 # via # -r requirements/test.txt # pytest-cov -cryptography==45.0.7 +cryptography==46.0.1 # via secretstorage ddt==1.7.2 # via -r requirements/test.txt @@ -85,7 +85,7 @@ docutils==0.21.2 # sphinx edx-ccx-keys==2.0.2 # via -r requirements/test.txt -edx-django-utils==8.0.0 +edx-django-utils==8.0.1 # via -r requirements/test.txt edx-opaque-keys[django]==3.0.0 # via @@ -132,7 +132,7 @@ keyring==25.6.0 # via twine markdown-it-py==4.0.0 # via rich -markupsafe==3.0.2 +markupsafe==3.0.3 # via # -r requirements/test.txt # jinja2 @@ -157,7 +157,7 @@ pluggy==1.6.0 # -r requirements/test.txt # pytest # pytest-cov -psutil==7.0.0 +psutil==7.1.0 # via # -r requirements/test.txt # edx-django-utils @@ -177,7 +177,7 @@ pygments==2.19.2 # readme-renderer # rich # sphinx -pymongo==4.15.0 +pymongo==4.15.1 # via # -r requirements/test.txt # edx-opaque-keys @@ -200,7 +200,7 @@ python-slugify==8.0.4 # via # -r requirements/test.txt # code-annotations -pyyaml==6.0.2 +pyyaml==6.0.3 # via # -r requirements/test.txt # code-annotations @@ -299,7 +299,7 @@ urllib3==2.5.0 # via # requests # twine -uvicorn==0.35.0 +uvicorn==0.37.0 # via sphinx-autobuild watchfiles==1.1.0 # via sphinx-autobuild diff --git a/requirements/pip-tools.txt b/requirements/pip-tools.txt index b19a4faa..d2ab0a75 100644 --- a/requirements/pip-tools.txt +++ b/requirements/pip-tools.txt @@ -6,7 +6,7 @@ # build==1.3.0 # via pip-tools -click==8.2.1 +click==8.3.0 # via pip-tools packaging==25.0 # via build diff --git a/requirements/quality.txt b/requirements/quality.txt index 8fea52c5..cf306bb5 100644 --- a/requirements/quality.txt +++ b/requirements/quality.txt @@ -4,7 +4,7 @@ # # make upgrade # -asgiref==3.9.1 +asgiref==3.9.2 # via # -r requirements/test.txt # django @@ -25,7 +25,7 @@ cffi==2.0.0 # pynacl charset-normalizer==3.4.3 # via requests -click==8.2.1 +click==8.3.0 # via # -r requirements/test.txt # click-log @@ -38,11 +38,11 @@ code-annotations==2.3.0 # via # -r requirements/test.txt # edx-lint -coverage[toml]==7.10.6 +coverage[toml]==7.10.7 # via # -r requirements/test.txt # pytest-cov -cryptography==45.0.7 +cryptography==46.0.1 # via secretstorage ddt==1.7.2 # via -r requirements/test.txt @@ -67,11 +67,11 @@ dnspython==2.8.0 # via # -r requirements/test.txt # pymongo -docutils==0.22 +docutils==0.22.2 # via readme-renderer edx-ccx-keys==2.0.2 # via -r requirements/test.txt -edx-django-utils==8.0.0 +edx-django-utils==8.0.1 # via -r requirements/test.txt edx-lint==5.6.0 # via -r requirements/quality.in @@ -113,7 +113,7 @@ keyring==25.6.0 # via twine markdown-it-py==4.0.0 # via rich -markupsafe==3.0.2 +markupsafe==3.0.3 # via # -r requirements/test.txt # jinja2 @@ -139,7 +139,7 @@ pluggy==1.6.0 # -r requirements/test.txt # pytest # pytest-cov -psutil==7.0.0 +psutil==7.1.0 # via # -r requirements/test.txt # edx-django-utils @@ -169,7 +169,7 @@ pylint-plugin-utils==0.9.0 # via # pylint-celery # pylint-django -pymongo==4.15.0 +pymongo==4.15.1 # via # -r requirements/test.txt # edx-opaque-keys @@ -190,7 +190,7 @@ python-slugify==8.0.4 # via # -r requirements/test.txt # code-annotations -pyyaml==6.0.2 +pyyaml==6.0.3 # via # -r requirements/test.txt # code-annotations @@ -207,7 +207,7 @@ rfc3986==2.0.0 # via twine rich==14.1.0 # via twine -ruff==0.13.0 +ruff==0.13.2 # via -r requirements/quality.in secretstorage==3.4.0 # via keyring diff --git a/requirements/test.txt b/requirements/test.txt index 3682acdd..9f00f010 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -4,7 +4,7 @@ # # make upgrade # -asgiref==3.9.1 +asgiref==3.9.2 # via # -r requirements/base.txt # django @@ -14,14 +14,14 @@ cffi==2.0.0 # via # -r requirements/base.txt # pynacl -click==8.2.1 +click==8.3.0 # via # -r requirements/base.txt # code-annotations # edx-django-utils code-annotations==2.3.0 # via -r requirements/test.in -coverage[toml]==7.10.6 +coverage[toml]==7.10.7 # via pytest-cov ddt==1.7.2 # via -r requirements/test.in @@ -45,7 +45,7 @@ dnspython==2.8.0 # pymongo edx-ccx-keys==2.0.2 # via -r requirements/base.txt -edx-django-utils==8.0.0 +edx-django-utils==8.0.1 # via -r requirements/base.txt edx-opaque-keys[django]==3.0.0 # via @@ -57,7 +57,7 @@ iniconfig==2.1.0 # via pytest jinja2==3.1.6 # via code-annotations -markupsafe==3.0.2 +markupsafe==3.0.3 # via jinja2 packaging==25.0 # via pytest @@ -65,7 +65,7 @@ pluggy==1.6.0 # via # pytest # pytest-cov -psutil==7.0.0 +psutil==7.1.0 # via # -r requirements/base.txt # edx-django-utils @@ -75,7 +75,7 @@ pycparser==2.23 # cffi pygments==2.19.2 # via pytest -pymongo==4.15.0 +pymongo==4.15.1 # via # -r requirements/base.txt # edx-opaque-keys @@ -93,7 +93,7 @@ pytest-django==4.11.1 # via -r requirements/test.in python-slugify==8.0.4 # via code-annotations -pyyaml==6.0.2 +pyyaml==6.0.3 # via code-annotations six==1.17.0 # via