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
42 changes: 33 additions & 9 deletions .github/workflows/compatibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ jobs:
- { os: ubuntu-24.04, python: '3.12', wheel: cp312-manylinux_x86_64 }
- { os: ubuntu-24.04, python: '3.13', wheel: cp313-manylinux_x86_64 }
- { os: ubuntu-24.04, python: '3.14', wheel: '' }
- { os: ubuntu-24.04, python: '3.15', wheel: cp315-manylinux_x86_64 }
- { os: windows-2025, python: '3.12', wheel: cp312-win_amd64 }
- { os: windows-2025, python: '3.13', wheel: cp313-win_amd64 }
- { os: windows-2025, python: '3.14', wheel: '' }
- { os: windows-2025, python: '3.15', wheel: cp315-win_amd64 }
defaults:
run:
shell: bash
Expand Down Expand Up @@ -59,13 +61,14 @@ jobs:
PY
cp .github/scripts/amulet_leveldb_smoke.py amulet-src/tests/test_backport_smoke.py
git -C amulet-src diff --check
- name: Setup Python
- name: Setup host Python
if: matrix.python != '3.15'
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python }}
- name: Install cibuildwheel
if: matrix.python != '3.14'
run: python -m pip install 'cibuildwheel~=4.1'
run: python -m pip install 'cibuildwheel==4.2.0'
- name: Build and test Amulet wheel
if: matrix.python != '3.14'
env:
Expand All @@ -81,6 +84,18 @@ jobs:
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Download exact Endstone CPython 3.15 Wheel
if: matrix.python == '3.15'
uses: actions/download-artifact@v8
with:
repository: EndstoneMC/endstone
run-id: 38045137884
github-token: ${{ github.token }}
pattern: endstone-*-cp315-cp315-*.whl
path: endstone-dist
merge-multiple: true
skip-decompress: true

- name: Test installed EndKeep with matched Amulet
run: |
uv venv .venv --python '${{ matrix.python }}'
Expand All @@ -89,15 +104,24 @@ jobs:
else
PYTHON=.venv/bin/python
fi
if [[ "${{ matrix.python }}" == "3.15" ]]; then
if [[ "${{ runner.os }}" == "Windows" ]]; then
ENDSTONE_WHEEL="$(find endstone-dist -name '*cp315*win_amd64.whl' -print -quit)"
else
ENDSTONE_WHEEL="$(find endstone-dist -name '*cp315*manylinux*.whl' -print -quit)"
fi
test -n "$ENDSTONE_WHEEL"
uv pip install --python "$PYTHON" "$ENDSTONE_WHEEL"
fi
# Fresh dependency resolution: do NOT seed the local Amulet build.
# This must fetch the exact published GitHub Release Wheel on 3.12/3.13.
# This must fetch the exact published GitHub Release Wheel on 3.12/3.13/3.15.
uv pip install --python "$PYTHON" -e '.[dev]'
"$PYTHON" - <<'PY'
from importlib.metadata import distribution
from packaging.requirements import Requirement
requires = distribution("endstone-endkeep").requires or []
amulet = [Requirement(req) for req in requires if Requirement(req).name == "amulet-leveldb"]
assert len(amulet) == 5, [str(req) for req in amulet]
assert len(amulet) == 7, [str(req) for req in amulet]
print("Packaged Amulet selectors:", *amulet, sep="\\n")
PY
uv pip check --python "$PYTHON"
Expand All @@ -118,11 +142,11 @@ jobs:
retention-days: 7

verified-backports:
name: Collect verified CPython 3.12/3.13 Wheels
name: Collect verified compatibility Wheels
needs: full-matrix
runs-on: ubuntu-24.04
steps:
- name: Download four tested wheel artifacts
- name: Download tested wheel artifacts
uses: actions/download-artifact@v4
with:
pattern: amulet-compat-*
Expand All @@ -138,8 +162,8 @@ jobs:

root = Path("dist")
wheels = sorted(root.glob("*.whl"))
assert len(wheels) == 4, [p.name for p in wheels]
for abi in ("cp312", "cp313"):
assert len(wheels) == 6, [p.name for p in wheels]
for abi in ("cp312", "cp313", "cp315"):
for platform in ("manylinux_", "win_amd64"):
matches = [
p for p in wheels
Expand All @@ -164,7 +188,7 @@ jobs:
- name: Upload verified wheel set for review (not a GitHub Release)
uses: actions/upload-artifact@v4
with:
name: amulet-backports-verified-four-wheels
name: amulet-backports-verified-six-wheels
path: |
dist/*.whl
dist/SHA256SUMS
Expand Down
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Working on EndKeep

EndKeep is a Python plugin for Endstone that creates incremental backups of
Minecraft Bedrock worlds. EndKeep targets Python 3.12–3.14
Minecraft Bedrock worlds. EndKeep targets Python 3.12–3.15
on Linux and Windows x86-64 with Endstone 0.11. For Endstone API usage, see
[Endstone's documentation](https://endstone.dev/).

Expand Down Expand Up @@ -36,11 +36,11 @@ uv run --no-sync pytest
- Update user documentation for visible behavior changes. Explain what server
owners need to do; keep internal implementation notes out of usage guides.
- Do not create releases or rewrite version tags unless explicitly requested.
- Python 3.12/3.13 resolves pinned, SHA256-verified Amulet-LevelDB compatibility
- Python 3.12/3.13/3.15 resolves pinned, SHA256-verified Amulet-LevelDB compatibility
Wheels from the dedicated GitHub Release. Test a clean EndKeep install without
pre-installing the dependency. The upstream Amulet version metadata currently prevents regenerating a
universal uv.lock; prefer `uv pip install` instead of `uv sync`.
- The six-combination compatibility workflow is not a substitute for
- The eight-combination compatibility workflow is not a substitute for
testing real BDS worlds, especially NTFS crash and directory metadata durability.

See [Contributing](CONTRIBUTING.md) and the
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [Unreleased]

### Added
- Support Python 3.15 on Linux and Windows x86-64 using SHA256-pinned Amulet-LevelDB 3.0.7a0 compatibility Wheels.
- Validate Python 3.15 against Endstone CPython 3.15 development Wheels in bds-test-lab.

## [0.3.0] - 2026-10-10

### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ without storing a complete world copy each time, and lets you restore an earlier

## Installation

Requires **Endstone 0.11** and **Python 3.12–3.14**.
Requires **Endstone 0.11** and **Python 3.12–3.15**.

1. Download the plugin `.whl` from [Releases](https://github.com/ReallocAll/endkeep/releases/latest).
2. Place it in the server's `plugins/` directory.
Expand Down
7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ name = "endstone-endkeep"
dynamic = ["version"]
dependencies = [
"endstone>=0.11,<0.12",
# Official upstream Wheel for Python 3.14; pinned, tested backports for 3.12 and 3.13.
# Official upstream Wheel for Python 3.14; SHA256-pinned compatibility Wheels for 3.12, 3.13 and 3.15.
"amulet-leveldb==3.0.7a0; python_version == '3.14'",
'amulet-leveldb @ https://github.com/ReallocAll/endkeep/releases/download/amulet-leveldb-3.0.7a0-compat-cp312-cp313/amulet_leveldb-3.0.7a0%2B0.g736228e.dirty-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=283e7e57e4d15d7ee59457a89db8c43be9a1cd85c7174844f3a1f1bd14d93bbd ; python_version == "3.12" and sys_platform == "linux" and platform_machine == "x86_64"',
'amulet-leveldb @ https://github.com/ReallocAll/endkeep/releases/download/amulet-leveldb-3.0.7a0-compat-cp312-cp313/amulet_leveldb-3.0.7a0%2B0.g736228e.dirty-cp312-cp312-win_amd64.whl#sha256=9033156a570ceef3613486a681b990f442788b636da1018838eb6ffdd3dca73f ; python_version == "3.12" and sys_platform == "win32" and platform_machine == "AMD64"',
'amulet-leveldb @ https://github.com/ReallocAll/endkeep/releases/download/amulet-leveldb-3.0.7a0-compat-cp312-cp313/amulet_leveldb-3.0.7a0%2B0.g736228e.dirty-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=718d5ff3887b4d848f811a49ab6a7fe3e0b1f863821029190714c4ea5362d9fc ; python_version == "3.13" and sys_platform == "linux" and platform_machine == "x86_64"',
'amulet-leveldb @ https://github.com/ReallocAll/endkeep/releases/download/amulet-leveldb-3.0.7a0-compat-cp312-cp313/amulet_leveldb-3.0.7a0%2B0.g736228e.dirty-cp313-cp313-win_amd64.whl#sha256=28dc6037e3d16355a5120baba1ec61065d020f65500ca9de20d97deaaac0ab2f ; python_version == "3.13" and sys_platform == "win32" and platform_machine == "AMD64"',
'amulet-leveldb @ https://github.com/ReallocAll/endkeep/releases/download/amulet-leveldb-3.0.7a0-compat-cp315/amulet_leveldb-3.0.7a0%2B0.g736228e.dirty-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=7fec1e03a2d72d1c08944726c08909fd811cf7ad905e6f124cea581bcfc554ad ; python_version == "3.15" and sys_platform == "linux" and platform_machine == "x86_64"',
'amulet-leveldb @ https://github.com/ReallocAll/endkeep/releases/download/amulet-leveldb-3.0.7a0-compat-cp315/amulet_leveldb-3.0.7a0%2B0.g736228e.dirty-cp315-cp315-win_amd64.whl#sha256=a54e2004f50b8fe5ac2a23edb7cd5c5e60fbc9a8d44fadf282e17b0d3416a611 ; python_version == "3.15" and sys_platform == "win32" and platform_machine == "AMD64"',
"zstandard>=0.23,<1",
"tomlkit>=0.13,<1",
]
Expand All @@ -23,7 +25,7 @@ description = "Crash-safe logical incremental world backups for Endstone"
readme = "README.md"
license = { file = "LICENSE" }
keywords = ["endstone", "minecraft", "bedrock", "backup", "leveldb"]
requires-python = ">=3.12,<3.15"
requires-python = ">=3.12,<3.16"
classifiers = [
"License :: OSI Approved :: MIT License",
"Operating System :: POSIX :: Linux",
Expand All @@ -32,6 +34,7 @@ classifiers = [
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3.15",
]

[project.optional-dependencies]
Expand Down
Loading