From 97d88644e32c353a3e900f0a2a0dff0aaf9d0970 Mon Sep 17 00:00:00 2001 From: Marcus Read Date: Thu, 2 Oct 2025 22:00:49 +0100 Subject: [PATCH] Migrate to `uv` Migrates ci from `pip` to `uv`. Revises test and release workflows. --- .github/dependabot.yml | 7 +- .github/workflows/build-test.yml | 26 ++++--- .github/workflows/release.yml | 86 ++++++++++------------ .python-version | 1 + pyproject.toml | 6 ++ requirements.txt | 8 +-- requirements_dev.txt | 120 ------------------------------- requirements_tests.txt | 54 -------------- setup.py | 9 --- uv.lock | 6 +- 10 files changed, 64 insertions(+), 259 deletions(-) create mode 100644 .python-version delete mode 100644 requirements_dev.txt delete mode 100644 requirements_tests.txt delete mode 100644 setup.py diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e4273d6..e451da4 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,9 +5,8 @@ version: 2 updates: - # Configuration for pip - # - package-ecosystem: "pip" # See documentation for possible values - # directory: "/etc/requirements_dependabot" # Location of package manifests + # - package-ecosystem: "uv" # See documentation for possible values + # directory: "/" # Location of package manifests # schedule: # interval: "daily" # for reference: @@ -23,4 +22,4 @@ updates: - package-ecosystem: "github-actions" # See documentation for possible values directory: "/" # Location of package manifests schedule: - interval: "weekly" + interval: "monthly" diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index ab182ff..cbbc9ef 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -23,19 +23,17 @@ jobs: python-version: ["3.9", "3.13"] steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + - uses: actions/checkout@v5 + - name: Install uv and set the Python version + uses: astral-sh/setup-uv@v6 with: python-version: ${{ matrix.python-version }} - cache: 'pip' - cache-dependency-path: 'requirements_tests.txt' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements_tests.txt - pip install -e . - - name: Test with pytest - # fail it if doesn't pass test suite - run: | - pytest + - name: Enable caching + uses: astral-sh/setup-uv@v6 + with: + enable-cache: true + + - name: Install the project + run: uv sync --locked --group test --no-dev + - name: Run tests + run: uv run pytest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 282fa6d..a1be0d6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,58 +6,46 @@ on: types: [released] permissions: + id-token: write contents: read jobs: deploy: runs-on: ubuntu-latest + environment: + name: pypi steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Install build dependencies - run: | - python -m pip install --upgrade pip - pip install build - - - name: Build package - run: python -m build - - - name: Publish to Test PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - with: - user: __token__ - password: ${{ secrets.PYPI_TEST_API_TOKEN }} - repository-url: https://test.pypi.org/legacy/ - - - name: Install from testpypi and import - run: | - sleep 5 - while [ "${{ github.ref_name }}" != $(pip index versions -i https://test.pypi.org/simple --pre valimp | cut -d'(' -f2 | cut -d')' -f1 | sed 1q) ];\ - do echo "waiting for package to appear in test index, sleeping 5s"; sleep 5s; echo "woken up"; done - pip install --index-url https://test.pypi.org/simple valimp==${{ github.ref_name }} --no-deps - pip install -r requirements.txt - python -c 'import valimp;print(valimp.__version__)' - - - name: Clean pip - run: | - pip uninstall -y valimp - pip cache purge - - - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - with: - user: __token__ - password: ${{ secrets.PYPI_API_TOKEN }} - - - name: Install and import - run: | - sleep 5 - while [ "${{ github.ref_name }}" != $(pip index versions -i https://pypi.org/simple --pre valimp | cut -d'(' -f2 | cut -d')' -f1 | sed 1q) ];\ - do echo "waiting for package to appear in index, sleeping 5s"; sleep 5s; echo "woken up"; done - pip install --index-url https://pypi.org/simple valimp==${{ github.ref_name }} - python -c 'import valimp;print(valimp.__version__)' + - uses: actions/checkout@v5 + - name: Install uv + uses: astral-sh/setup-uv@v6 + - name: Install Python + run: uv python install + - name: Build + run: uv build + + - name: Publish to Test PyPI + run: uv publish --index testpypi + - name: Check test install and import + run: | + sleep 5 # Wait for Test Pypi to publish + uv run \ + --with valimp \ + --refresh-package valimp \ + --index https://test.pypi.org/simple \ + --no-project \ + --isolated \ + -- \ + python -c 'import valimp; print(f"{valimp.__version__=}")' + + - name: Publish to PyPI + run: uv publish + - name: Check install and import + run: | + sleep 5 # Wait for Pypi to publish + uv run \ + --with valimp \ + --refresh-package valimp \ + --no-project \ + --isolated \ + -- \ + python -c 'import valimp;print(f"{valimp.__version__=}")' diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..bd28b9c --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.9 diff --git a/pyproject.toml b/pyproject.toml index 5b85f77..c17dcac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,3 +62,9 @@ documentation = "https://github.com/maread99/valimp" [tool.setuptools_scm] write_to = "src/valimp/_version.py" + +[[tool.uv.index]] +name = "testpypi" +url = "https://test.pypi.org/simple/" +publish-url = "https://test.pypi.org/legacy/" +explicit = true diff --git a/requirements.txt b/requirements.txt index 18de4ba..8cc88aa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,2 @@ -# -# This file is autogenerated by pip-compile with Python 3.9 -# by the following command: -# -# pip-compile pyproject.toml -# +# This file was autogenerated by uv via the following command: +# uv export --format requirements-txt --no-emit-project --no-hashes --no-dev -o requirements.txt diff --git a/requirements_dev.txt b/requirements_dev.txt deleted file mode 100644 index 593e131..0000000 --- a/requirements_dev.txt +++ /dev/null @@ -1,120 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.9 -# by the following command: -# -# pip-compile --extra=dev --output-file=requirements_dev.txt pyproject.toml -# -astroid==3.3.8 - # via pylint -black==24.10.0 - # via valimp (pyproject.toml) -build==1.2.2.post1 - # via pip-tools -cfgv==3.4.0 - # via pre-commit -click==8.1.8 - # via - # black - # pip-tools -colorama==0.4.6 - # via - # build - # click - # pylint - # pytest -dill==0.3.9 - # via pylint -distlib==0.3.9 - # via virtualenv -exceptiongroup==1.2.2 - # via pytest -filelock==3.16.1 - # via virtualenv -flake8==7.1.1 - # via - # flake8-docstrings - # valimp (pyproject.toml) -flake8-docstrings==1.7.0 - # via valimp (pyproject.toml) -identify==2.6.5 - # via pre-commit -importlib-metadata==8.5.0 - # via build -iniconfig==2.0.0 - # via pytest -isort==5.13.2 - # via pylint -mccabe==0.7.0 - # via - # flake8 - # pylint -mypy==1.14.1 - # via valimp (pyproject.toml) -mypy-extensions==1.0.0 - # via - # black - # mypy -nodeenv==1.9.1 - # via pre-commit -packaging==24.2 - # via - # black - # build - # pytest -pathspec==0.12.1 - # via black -pip-tools==7.4.1 - # via valimp (pyproject.toml) -platformdirs==4.3.6 - # via - # black - # pylint - # virtualenv -pluggy==1.5.0 - # via pytest -pre-commit==4.0.1 - # via valimp (pyproject.toml) -pycodestyle==2.12.1 - # via flake8 -pydocstyle==6.3.0 - # via flake8-docstrings -pyflakes==3.2.0 - # via flake8 -pylint==3.3.3 - # via valimp (pyproject.toml) -pyproject-hooks==1.2.0 - # via - # build - # pip-tools -pytest==8.3.4 - # via valimp (pyproject.toml) -pyyaml==6.0.2 - # via pre-commit -snowballstemmer==2.2.0 - # via pydocstyle -tomli==2.2.1 - # via - # black - # build - # mypy - # pip-tools - # pylint - # pytest -tomlkit==0.13.2 - # via pylint -typing-extensions==4.12.2 - # via - # astroid - # black - # mypy - # pylint -virtualenv==20.28.1 - # via pre-commit -wheel==0.45.1 - # via pip-tools -zipp==3.21.0 - # via importlib-metadata - -# The following packages are considered to be unsafe in a requirements file: -# pip -# setuptools diff --git a/requirements_tests.txt b/requirements_tests.txt deleted file mode 100644 index f11941e..0000000 --- a/requirements_tests.txt +++ /dev/null @@ -1,54 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.9 -# by the following command: -# -# pip-compile --extra=tests --output-file=requirements_tests.txt pyproject.toml -# -black==24.10.0 - # via valimp (pyproject.toml) -click==8.1.8 - # via black -colorama==0.4.6 - # via - # click - # pytest -exceptiongroup==1.2.2 - # via pytest -flake8==7.1.1 - # via - # flake8-docstrings - # valimp (pyproject.toml) -flake8-docstrings==1.7.0 - # via valimp (pyproject.toml) -iniconfig==2.0.0 - # via pytest -mccabe==0.7.0 - # via flake8 -mypy-extensions==1.0.0 - # via black -packaging==24.2 - # via - # black - # pytest -pathspec==0.12.1 - # via black -platformdirs==4.3.6 - # via black -pluggy==1.5.0 - # via pytest -pycodestyle==2.12.1 - # via flake8 -pydocstyle==6.3.0 - # via flake8-docstrings -pyflakes==3.2.0 - # via flake8 -pytest==8.3.4 - # via valimp (pyproject.toml) -snowballstemmer==2.2.0 - # via pydocstyle -tomli==2.2.1 - # via - # black - # pytest -typing-extensions==4.12.2 - # via black diff --git a/setup.py b/setup.py deleted file mode 100644 index 19d3ae1..0000000 --- a/setup.py +++ /dev/null @@ -1,9 +0,0 @@ -# noqa: D100 -# This file is currently (2022-06) required in order for pip to be able to create -# editable installs when build meta is included to pyproject.toml. Likely that at -# some future point this will no longer be required and file can be removed. -# Reference: https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html - -from setuptools import setup - -setup() diff --git a/uv.lock b/uv.lock index a935df5..e2b9278 100644 --- a/uv.lock +++ b/uv.lock @@ -52,11 +52,11 @@ wheels = [ [[package]] name = "identify" -version = "2.6.14" +version = "2.6.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/c4/62963f25a678f6a050fb0505a65e9e726996171e6dbe1547f79619eefb15/identify-2.6.14.tar.gz", hash = "sha256:663494103b4f717cb26921c52f8751363dc89db64364cd836a9bf1535f53cd6a", size = 99283, upload-time = "2025-09-06T19:30:52.938Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/e7/685de97986c916a6d93b3876139e00eef26ad5bbbd61925d670ae8013449/identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf", size = 99311, upload-time = "2025-10-02T17:43:40.631Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/ae/2ad30f4652712c82f1c23423d79136fbce338932ad166d70c1efb86a5998/identify-2.6.14-py2.py3-none-any.whl", hash = "sha256:11a073da82212c6646b1f39bb20d4483bfb9543bd5566fec60053c4bb309bf2e", size = 99172, upload-time = "2025-09-06T19:30:51.759Z" }, + { url = "https://files.pythonhosted.org/packages/0f/1c/e5fd8f973d4f375adb21565739498e2e9a1e54c858a97b9a8ccfdc81da9b/identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757", size = 99183, upload-time = "2025-10-02T17:43:39.137Z" }, ] [[package]]