Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate from poetry & tox to uv #950

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
uses: ./.github/workflows/validation.yml

unit-tests:
uses: ./.github/workflows/tox-test.yml
uses: ./.github/workflows/unit-tests.yml

# Produce a pull request payload artifact with various data about the
# pull-request event (such as the PR number, title, author, ...).
Expand Down
31 changes: 22 additions & 9 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ permissions:
id-token: write # Used to authenticate to PyPI via OIDC.
contents: read

env:
PYTHON_VERSION: "3.13"

jobs:
deploy:
runs-on: ubuntu-latest
Expand All @@ -20,18 +23,28 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup poetry
id: poetry_setup
uses: ItsDrike/setup-poetry@v1
- name: Setup uv
uses: astral-sh/setup-uv@v5
with:
python-version: 3.13
install-args: "--with release"

- name: Prepare pyproject.toml with dynamic version
run: poetry run poetry-dynamic-versioning
version: "latest"
python-version: ${{ env.PYTHON_VERSION }}
enable-cache: true
cache-suffix: "publish-ci"

- name: Make sure pyproject.toml version matches git version
run: |
git_version=$(git describe)
pyproject_version=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")

if [ "$git_verson" != "$pyproject_version" ]; then
echo "The version specified in pyproject.toml ($pyproject_version) doesn't match the git version ($git_verson)"
echo "You most likely forgot to update pyproject.toml when publishing the release tag"
echo "You can fix this by updating the pyproject version and overwriting the git tag"
exit 1
fi

- name: Build package
run: poetry build
run: uv build

# This uses PyPI's trusted publishing, so no token is required
- name: Publish package distributions to PyPI
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: Tox test
name: Unit-Tests

on: workflow_call

jobs:
tox-test:
unit-tests:
runs-on: ${{ matrix.platform }}

strategy:
Expand All @@ -16,25 +16,29 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup poetry
id: poetry_setup
uses: ItsDrike/setup-poetry@v1
- name: Setup uv
uses: astral-sh/setup-uv@v5
with:
install-args: "--with workflow-tox --without lint"
python-version: "${{ matrix.python-version }}"
version: "latest"
python-version: ${{ matrix.python-version }}
enable-cache: true
cache-suffix: "test-ci"

- name: Test with tox
- name: Install dependencies
run: |
# Only install the test group dependencies + the project itself
uv sync --no-group dev --no-group lint --no-group docs

- name: Run pytest
shell: bash
run: poetry run tox
env:
PIP_USER: 0 # We want tox to use it's environments, not user installs
run: pytest -vv

# This job is used purely to provide a workflow status, which we can mark as a
# required action in branch protection rules. This is a better option than marking
# the tox-test jobs manually, since their names cnange as the supported python
# versions change. This job provides an easy single action that can be marked required.
tests-done:
needs: [tox-test]
needs: [unit-tests]
if: always() && !cancelled()
runs-on: ubuntu-latest

Expand Down
30 changes: 24 additions & 6 deletions .github/workflows/validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ name: Validation
on: workflow_call

env:
PYTHON_VERSION: "3.13"
PRE_COMMIT_HOME: "/home/runner/.cache/pre-commit"

jobs:
Expand All @@ -13,26 +14,40 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup poetry
id: poetry_setup
uses: ItsDrike/setup-poetry@v1
- name: Setup uv
uses: astral-sh/setup-uv@v5
with:
python-version: 3.13
version: "latest"
python-version: ${{ env.PYTHON_VERSION }}
enable-cache: true
cache-suffix: "validation-ci"

- name: Install dependencies
run: |
# Install the lint, test & docs dependency groups + the project's core deps.
# We need the test & docs groups to allow pyright to type-check the code in tests/ & docs/
uv sync --no-group dev

- name: Get precommit version
id: precommit_version
run: |
PACKAGE_VERSION=$(pip show pre-commit | grep -i "version:" | awk '{print $2}')
echo "version=$PACKAGE_VERSION" >> $GITHUB_ENV

- name: Pre-commit Environment Caching
uses: actions/cache@v4
with:
path: ${{ env.PRE_COMMIT_HOME }}
key:
"precommit-${{ runner.os }}-${{ steps.poetry_setup.outputs.python-version }}-\
"precommit-${{ runner.os }}-${{ env.PYTHON_VERSION }}-${{ steps.precommit_version.outputs.version }}-\
${{ hashFiles('./.pre-commit-config.yaml') }}"
# Restore keys allows us to perform a cache restore even if the full cache key wasn't matched.
# That way we still end up saving new cache, but we can still make use of the cache from previous
# version.
restore-keys: "precommit-${{ runner.os }}-${{ steps.poetry_setup.outputs-python-version}}-"

- name: Run pre-commit hooks
run: SKIP=black,isort,ruff,pyright pre-commit run --all-files
run: SKIP=black,isort,ruff,pyright,uv-lockfile pre-commit run --all-files

- name: Run ruff linter
run: ruff check --output-format=github --show-fixes --exit-non-zero-on-fix .
Expand All @@ -42,3 +57,6 @@ jobs:

- name: Run pyright type checker
run: pyright .

- name: Check UV Lockfile
run: uv lock --check
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage*
!.coveragerc
.cache
Expand Down
25 changes: 16 additions & 9 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,37 +18,44 @@ repos:
- id: end-of-file-fixer
- id: mixed-line-ending
- id: sort-simple-yaml
files: .pre-commit-config.yaml
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
hooks:
- id: python-check-blanket-noqa # Enforce noqa annotations (noqa: F401,W203)
- id: python-use-type-annotations # Enforce type annotations instead of type comments

- repo: local
hooks:
- id: ruff
name: Ruff Linter
description: Run ruff checks on the code
entry: poetry run ruff check --force-exclude
entry: ruff check --force-exclude
language: system
types: [python]
require_serial: true
args: [--fix, --exit-non-zero-on-fix]

- repo: local
hooks:
- id: ruff-ruff
name: Ruff Formatter
description: Ruf ruff auto-formatter
entry: poetry run ruff format
entry: ruff format
language: system
types: [python]
require_serial: true

- repo: local
hooks:
- id: pyright
name: Pyright
description: Run pyright type checker
entry: poetry run pyright
entry: pyright
language: system
types: [python]
pass_filenames: false # pyright runs for the entire project, it can't run for single files

- repo: local
hooks:
- id: uv-lockfile
name: UV Lockfile
description: Check if the UV lockfile is up to date with pyproject.toml
entry: uv lock --check
language: system
files: '^pyproject\.toml$|^uv\.lock$'
pass_filenames: false
8 changes: 4 additions & 4 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ version: 2
build:
os: ubuntu-22.04
tools:
python: "3.12"
python: "3.13"

jobs:
post_create_environment:
- python -m pip install poetry
- python -m pip install uv
post_install:
- VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install --only main,docs
- poetry run poetry-dynamic-versioning
- UV_PROJECT_ENVIRONMENT=$READTHEDOCS_VIRTUALENV_PATH uv sync --all-extras --group docs --link-mode=copy

sphinx:
builder: dirhtml
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![current PyPI version](https://img.shields.io/pypi/v/mcstatus.svg)](https://pypi.org/project/mcstatus/)
[![Docs](https://img.shields.io/readthedocs/mcstatus?label=Docs)](https://mcstatus.readthedocs.io/)
[![Validation](https://github.com/py-mine/mcstatus/actions/workflows/validation.yml/badge.svg)](https://github.com/py-mine/mcstatus/actions/workflows/validation.yml)
[![Tox test](https://github.com/py-mine/mcstatus/actions/workflows/tox-test.yml/badge.svg)](https://github.com/py-mine/mcstatus/actions/workflows/tox-test.yml)
[![Unit Tests](https://github.com/py-mine/mcstatus/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/py-mine/mcstatus/actions/workflows/unit-tests.yml)

Mcstatus provides an API and command line script to fetch publicly available data from Minecraft servers. Specifically, mcstatus retrieves data by using these protocols: [Server List Ping](https://wiki.vg/Server_List_Ping) and [Query](https://wiki.vg/Query). Because of mcstatus, you do not need to fully understand those protocols and can instead skip straight to retrieving minecraft server data quickly in your own programs.

Expand Down Expand Up @@ -68,6 +68,7 @@ See the [documentation](https://mcstatus.readthedocs.io) to find what you can do
### Command Line Interface

The mcstatus library includes a simple CLI. Once installed, it can be used through:

```bash
python3 -m mcstatus --help
```
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

def _get_project_meta() -> dict[str, str]:
with open("../pyproject.toml", "rb") as pyproject:
return toml_parse(pyproject)["tool"]["poetry"] # type: ignore[no-any-return]
return toml_parse(pyproject)["project"] # type: ignore[no-any-return]


pkg_meta = _get_project_meta()
Expand Down
63 changes: 38 additions & 25 deletions docs/pages/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,20 @@ Setup

.. code-block:: sh

pipx install poetry
pipx inject poetry poetry-dynamic-versioning
pipx install tox
pipx inject tox tox-poetry
poetry run pre-commit install
pipx install uv
uv sync

In addition to those tools, you may also want to install flake8 and black
plugins for your IDE.
# The following command will depend on your operating system and shell.
# For MacOS/Linux:
. .venv/bin/activate
# For Windows CMD:
venv\Scripts\activate.bat
# For Windows PowerShell:
venv\Scripts\Activate.ps1

pre-commit install

In addition to this, you may also want to install ruff and pyright (pylance) plugins for your IDE.

Expectations
------------
Expand All @@ -35,32 +41,39 @@ Once you have all the checks passing and any new behavior changes are tested,
feel free to open a pull request. Pull requests are how GitHub allows forks to
submit branches for consideration to be merged into the original repo.

Running all the checks
----------------------
Common development tasks
------------------------

.. code-block:: sh

tox

Running a specific list of checks
---------------------------------

.. code-block:: sh

tox -e lint,py37,py38

Listing all the specific names that can be passed to ``-e``
-----------------------------------------------------------
# Activating the virtual environment, allowing you to work with the project's dependencies
# installed there by uv. This command is OS and shell dependent.
# For MacOS/Linux:
. .venv/bin/activate
# For Windows CMD:
venv\Scripts\activate.bat
# For Windows PowerShell:
venv\Scripts\Activate.ps1

poe docs # Renders documentation from docs/ folder
poe format # Executes automatic formatter for style consistency
poe lint # Executes linting tools that help increase code quality
poe test # Executes unit tests

Listing available tasks
-----------------------

.. code-block:: sh

tox -a
poe

Being fancy with pytest
-----------------------
Being fancy with tasks
----------------------

Any options you want to pass directly to pytest can be done after a double dash ``--``:
You may pass extra arguments to the underlying tasks. Here's an example that
tells the underlying ``pytest`` to execute only the query tests with maximum
verbosity.

.. code-block:: sh

tox -e py37 -- -vvv -k TestQuery
poe test -vvv -k TestQuery
Loading
Loading