Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
26 changes: 22 additions & 4 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,25 @@ Deploying

A reminder for maintainers on how to deploy:

#. Update the version in ``pyproject.toml`` and ``json2xml/__init__.py``.
#. Add the release notes to ``HISTORY.rst``.
#. Run ``make test-all`` and ``make dist``.
#. Publish the verified artifacts with ``uv publish dist/*``.
#. Update the version in ``pyproject.toml`` and ``json2xml/__init__.py``, then
regenerate ``uv.lock`` without unrelated dependency upgrades.
#. Add matching, versioned entries to ``HISTORY.rst`` and ``RELEASE_NOTES.md``.
Include security advisories, compatibility changes, upgrade instructions,
merged pull requests, and a comparison link from the previous Python tag.
Keep the date marked unreleased until publication is scheduled.
#. Run ``make check-all``, ``make test-rust``, ``uv lock --check``, and
``uv audit --locked``. Record any unavailable checks accurately. Build the
wheel and source distribution, verify their version and requirements, and
run Twine metadata checks. Wait for the release commit's hosted CI to pass.
#. Confirm the release date and target commit. Generate the GitHub changelog
from the previous Python ``v*`` tag, not an intervening ``rust-v*`` tag.
Combine the generated pull-request list with the matching curated release
section from ``RELEASE_NOTES.md``; do not paste notes for older releases.
#. Replace the unreleased markers with the release date and publish the
GitHub release against the verified commit using the matching ``v*`` tag.
Comment on lines +200 to +201

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Verify the dated release commit before publishing

When maintainers follow these steps literally, replacing the tracked unreleased markers requires a new commit after the previously selected commit passed hosted CI, yet this step then instructs them to publish against the “verified commit.” The dated commit is therefore unverified (or the published tag omits the required date changes); require committing the final markers and waiting for that exact commit's checks before creating the release.

Useful? React with 👍 / 👎.

The published-release workflow builds and uploads the Python package to
PyPI. Do not also run a duplicate manual upload. Use
``uv publish dist/*`` only as an intentional alternative publication path.
#. Verify the GitHub release notes and PyPI version, then smoke-test a fresh
installation and check the resolved dependencies. A successful GitHub
release creation alone does not establish that the PyPI upload succeeded.
8 changes: 8 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
8.0.1 / Unreleased
==================

* security: require ``urllib3>=2.8.0`` to exclude versions affected by CVE-2026-97687, CVE-2026-97688, and CVE-2026-97689 (PR #456)
* build: lock urllib3 to 2.8.0 with updated distribution hashes and align standalone benchmark dependency requirements
* compatibility: retain Python >=3.11 and the optional ``json2xml-rs>=1.0.0`` accelerator; conversion APIs and XML output are unchanged


8.0.0 / 2026-10-12
==================

Expand Down
46 changes: 46 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,49 @@
# json2xml 8.0.1

Unreleased — publication date will be recorded when the release is scheduled.

## Security fixes

Require `urllib3>=2.8.0` so new installations cannot select releases affected by the following upstream advisories:

| Advisory | Severity | Upstream issue | Fixed in |
| --- | --- | --- | --- |
| [CVE-2026-97687 / GHSA-8988-9cw3-xx77](https://github.com/urllib3/urllib3/security/advisories/GHSA-8988-9cw3-xx77) | High | HTTPS proxy TLS settings | urllib3 2.8.0 |
| [CVE-2026-97688 / GHSA-gh4c-6fx4-qh6g](https://github.com/urllib3/urllib3/security/advisories/GHSA-gh4c-6fx4-qh6g) | Moderate | Deflate streaming loop | urllib3 2.8.0 |
| [CVE-2026-97689 / GHSA-vxq7-64xx-v4gw](https://github.com/urllib3/urllib3/security/advisories/GHSA-vxq7-64xx-v4gw) | High | Unbounded chunk-size buffering | urllib3 2.8.0 |

The root lockfile selects urllib3 2.8.0 with updated distribution hashes. Standalone benchmark commands use the same secure minimum. No other dependency versions were upgraded in the security fix.

## Compatibility and upgrade

Python 3.11 or later remains required. Conversion APIs and XML output are unchanged. The optional accelerator remains `json2xml-rs>=1.0.0`; this release does not include a new Rust package.

After 8.0.1 is published, upgrade with:

```sh
python -m pip install --upgrade 'json2xml==8.0.1'
# With the optional accelerator:
python -m pip install --upgrade 'json2xml[fast]==8.0.1'
```

Downstream projects that maintain their own lockfiles should regenerate them and confirm that urllib3 resolves to 2.8.0 or later.

## Validation

The security fix in [PR #456](https://github.com/vinitkumar/json2xml/pull/456) passed all 37 reported GitHub checks and the Snyk and Read the Docs commit statuses. Hosted tests covered CPython 3.11–3.15, free-threaded 3.14, and PyPy 3.11 across Linux, macOS, Windows, and Linux ARM64 where configured.

Local validation of that fix passed Ruff, ty, 509 Python tests with 149 optional Rust tests skipped, and 100% statement coverage. The locked dependency audit and wheel/source builds passed. Native Rust tests were not run locally because Cargo was unavailable; no Rust sources changed.

The 8.0.1 release preparation also passed local Ruff, ty, 509 tests with 149 optional Rust tests skipped, 100% statement coverage, lockfile validation, the dependency audit, and architecture documentation checks. Both built distributions passed Twine metadata checks and declare version 8.0.1, Python >=3.11, and urllib3>=2.8.0. The release commit's hosted CI must pass before publication; record those results and the publication date before publishing.

## Changelog

- [#456](https://github.com/vinitkumar/json2xml/pull/456): require urllib3 2.8.0 for security fixes.
- [Full changelog from v8.0.0 to v8.0.1](https://github.com/vinitkumar/json2xml/compare/v8.0.0...v8.0.1) (available after the release tag is created).

Generate the GitHub release changelog from the previous **Python** tag, `v8.0.0`, and combine it with this release's curated security notes. Do not use a `rust-v*` tag as the comparison baseline.


# json2xml 8.0.0

Released 2026-10-12.
Expand Down
2 changes: 1 addition & 1 deletion json2xml/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

__author__ = """Vinit Kumar"""
__email__ = "mail@vinitkumar.me"
__version__ = "8.0.0"
__version__ = "8.0.1"
2 changes: 1 addition & 1 deletion lat.md/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Package releases keep the Python wrapper and Rust accelerator requirements align

Python 8.0.0 and Rust accelerator 1.0.0 require Python 3.11 or later. The Python `fast` extra requires `json2xml-rs>=1.0.0`; Python 3.10 users must stay on Python package 7.x. CI covers CPython and PyPy 3.11+; older interpreter jobs are excluded.

The Python package version lives in `pyproject.toml` and `json2xml/__init__.py`. The Rust accelerator version lives in both `rust/Cargo.toml` and `rust/pyproject.toml`, with `rust/uv.lock` synchronized, and the Python `fast` extra should require the Rust package version that contains any expected accelerator behavior. Publish and verify the Rust package before updating that Python requirement and lockfile. Release notes live in `HISTORY.rst`, with the current release also summarized in `RELEASE_NOTES.md` for tag and PyPI copy.
The Python package version lives in `pyproject.toml` and `json2xml/__init__.py`. The Rust accelerator version lives in both `rust/Cargo.toml` and `rust/pyproject.toml`, with `rust/uv.lock` synchronized, and the Python `fast` extra should require the Rust package version that contains any expected accelerator behavior. Publish and verify the Rust package before updating that Python requirement and lockfile. Release notes live in `HISTORY.rst`, with the current release also summarized in `RELEASE_NOTES.md` for tag and PyPI copy. Each release includes matching versioned entries, security advisories and upgrade guidance where applicable, verified check results, and a changelog comparison from the previous Python `v*` tag rather than an intervening Rust tag. The release stays marked unreleased until its publication is scheduled. Publishing a Python GitHub release triggers the PyPI workflow; verify the registry upload and a fresh install separately.

## Performance benchmarks

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "json2xml"
version = "8.0.0"
version = "8.0.1"
description = "Simple Python Library to convert JSON to XML"
readme = "README.rst"
requires-python = ">=3.11"
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading