Skip to content
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
9 changes: 7 additions & 2 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:

env:
PYTHON_DEFAULT_VERSION: "3.12"
UV_VERSION: "0.8.24"

jobs:
deploy:
Expand All @@ -26,13 +27,17 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_DEFAULT_VERSION }}
- uses: astral-sh/setup-uv@v7
with:
version: ${{ env.UV_VERSION }}
enable-cache: true
- name: Display Python version
run: python -c "import sys; print(sys.version)"
- name: Install dependencies
run: python -m pip install --upgrade nox pdm==2.26.2
run: uv sync --only-group nox --locked
- name: Build the distribution
id: build
run: nox -vs build
run: uv run nox -vs build
- name: Read the Changelog
id: read-changelog
uses: mindsers/changelog-reader-action@v2
Expand Down
54 changes: 36 additions & 18 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:

env:
PYTHON_DEFAULT_VERSION: "3.12"
UV_VERSION: "0.8.24"

jobs:
lint:
Expand All @@ -24,17 +25,20 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_DEFAULT_VERSION }}
cache: "pip"
- uses: astral-sh/setup-uv@v7
with:
version: ${{ env.UV_VERSION }}
enable-cache: true
- name: Install dependencies
run: python -m pip install --upgrade nox pdm==2.26.2
run: uv sync --only-group nox --locked
- name: Run linters
run: nox -vs lint
run: uv run nox -vs lint
- name: Validate new changelog entries
if: (contains(github.event.pull_request.labels.*.name, '-changelog') == false) && (github.event.pull_request.base.ref != '')
run: if [ -z "$(git diff --diff-filter=A --name-only origin/${{ github.event.pull_request.base.ref }} changelog.d)" ];
then echo no changelog item added; exit 1; fi
- name: Changelog validation
run: nox -vs towncrier_check
run: uv run nox -vs towncrier_check
build:
timeout-minutes: 30
needs: lint
Expand All @@ -47,11 +51,14 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_DEFAULT_VERSION }}
cache: "pip"
- uses: astral-sh/setup-uv@v7
with:
version: ${{ env.UV_VERSION }}
enable-cache: true
- name: Install dependencies
run: python -m pip install --upgrade nox pdm==2.26.2
run: uv sync --only-group nox --locked
- name: Build the distribution
run: nox -vs build
run: uv run nox -vs build
cleanup_buckets:
timeout-minutes: 30
needs: lint
Expand All @@ -69,13 +76,17 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_DEFAULT_VERSION }}
cache: "pip"
- uses: astral-sh/setup-uv@v7
if: ${{ env.B2_TEST_APPLICATION_KEY != '' && env.B2_TEST_APPLICATION_KEY_ID != '' }} # TODO: skip this whole job instead
with:
version: ${{ env.UV_VERSION }}
enable-cache: true
- name: Install dependencies
if: ${{ env.B2_TEST_APPLICATION_KEY != '' && env.B2_TEST_APPLICATION_KEY_ID != '' }} # TODO: skip this whole job instead
run: python -m pip install --upgrade nox pdm==2.26.2
run: uv sync --only-group nox --locked
- name: Find and remove old buckets
if: ${{ env.B2_TEST_APPLICATION_KEY != '' && env.B2_TEST_APPLICATION_KEY_ID != '' }} # TODO: skip this whole job instead
run: nox -vs cleanup_old_buckets
run: uv run nox -vs cleanup_old_buckets
test:
timeout-minutes: 90
needs: cleanup_buckets
Expand Down Expand Up @@ -107,14 +118,17 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
cache: "pip"
- uses: astral-sh/setup-uv@v7
with:
version: ${{ env.UV_VERSION }}
enable-cache: true
- name: Install dependencies
run: python -m pip install --upgrade nox pdm==2.26.2
run: uv sync --only-group nox --locked
- name: Run unit tests
run: nox -vs unit -- -v
run: uv run nox -vs unit -- -v
- name: Run integration tests
if: ${{ env.B2_TEST_APPLICATION_KEY != '' && env.B2_TEST_APPLICATION_KEY_ID != '' }}
run: nox -vs integration -- --dont-cleanup-old-buckets -v
run: uv run nox -vs integration -- --dont-cleanup-old-buckets -v
doc:
timeout-minutes: 30
needs: build
Expand All @@ -127,13 +141,17 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_DEFAULT_VERSION }}
cache: "pip"
- name: Install dependencies
- uses: astral-sh/setup-uv@v7
with:
version: ${{ env.UV_VERSION }}
enable-cache: true
- name: Install system dependencies
env:
DEBIAN_FRONTEND: noninteractive
run: |
sudo apt-get update -y
sudo apt-get install -y graphviz plantuml
python -m pip install --upgrade nox pdm==2.26.2
- name: Install dependencies
run: uv sync --only-group nox --locked
- name: Build the docs
run: nox --non-interactive -vs doc
run: uv run nox --non-interactive -vs doc
4 changes: 2 additions & 2 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ build:
- graphviz
jobs:
post_create_environment:
- pip install pdm
- pdm export --format requirements --group doc --output requirements-doc.txt
- python -m pip install uv==0.8.4
- uv export --format requirements-txt --group doc --output-file requirements-doc.txt

# Build documentation in the docs/ directory with Sphinx
sphinx:
Expand Down
12 changes: 6 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ for a given github issue).

## Developer Info

You'll need to have [nox](https://github.com/theacodes/nox) and [pdm](https://pdm-project.org/) installed:
You'll need to have [nox](https://github.com/theacodes/nox) and [uv](https://docs.astral.sh/uv/) installed:

* `pip install nox pdm`
* `pip install nox uv`

With `nox`, you can run different sessions (default are `lint` and `test`):

Expand Down Expand Up @@ -99,11 +99,11 @@ Given Python interpreters should be installed in the operating system or via [py

## Managing dependencies

We use [pdm](https://pdm-project.org/) for managing dependencies and developing locally.
We use [uv](https://docs.astral.sh/uv/) for managing dependencies and developing locally.
If you want to change any of the project requirements (or requirement bounds) in `pyproject.toml`,
make sure that `pdm.lock` file reflects those changes by using `pdm add`, `pdm update` or other
commands - see [documentation](https://pdm-project.org/latest/). You can verify that lock file
is up to date by running the linter.
make sure that `uv.lock` file reflects those changes by using `uv add`, `uv lock` or other
commands - see [documentation](https://docs.astral.sh/uv/). You can verify that the lock file
is up to date by running `uv lock --check`.

## Linting

Expand Down
1 change: 1 addition & 0 deletions changelog.d/+nox-dev-group.infrastructure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Use a separate nox dependency group for reprocible installs of nox in ci / cd.
1 change: 1 addition & 0 deletions changelog.d/+pdm-to-uv.infrastructure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Migrate from pdm to uv.
49 changes: 25 additions & 24 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@

UPSTREAM_REPO_URL = 'git@github.com:Backblaze/b2-sdk-python.git'

# Required for PDM to use nox's virtualenvs
os.environ.update({'PDM_IGNORE_SAVED_PYTHON': '1'})

CI = os.environ.get('CI') is not None
NOX_PYTHONS = os.environ.get('NOX_PYTHONS')
_NOX_EXTRAS = os.environ.get('NOX_EXTRAS')
Expand Down Expand Up @@ -59,20 +56,27 @@ def _detect_python_nox_id() -> str:

PY_PATHS = ['b2sdk', 'test', 'noxfile.py']

nox.options.reuse_existing_virtualenvs = True
nox.options.default_venv_backend = 'uv'
nox.options.reuse_existing_virtualenvs = False
nox.options.sessions = [
'lint',
'test',
]


def pdm_install(session: nox.Session, *args: str, dev: bool = True) -> None:
# dev dependencies are installed by default
prod_args = [] if dev else ['--prod']
group_args = []
for group in args:
group_args.extend(['--group', group])
session.run('pdm', 'install', *prod_args, *group_args, external=True)
def uv_install(
session: nox.Session, *, groups: tuple[str, ...] = (), extras: tuple[str, ...] = ()
) -> None:
args = ['sync', '--locked']
for group in groups:
if group:
args.extend(['--group', group])
for extra in extras:
if extra:
args.extend(['--extra', extra])
uv_env = getattr(session.virtualenv, 'location', os.getenv('VIRTUAL_ENV'))

session.run_install('uv', *args, env={'UV_PROJECT_ENVIRONMENT': uv_env})


def skip_coverage(python_version: str | None) -> bool:
Expand All @@ -82,7 +86,7 @@ def skip_coverage(python_version: str | None) -> bool:
@nox.session(name='format', python=PYTHON_DEFAULT_VERSION)
def format_(session):
"""Lint the code and apply fixes in-place whenever possible."""
pdm_install(session, 'lint')
uv_install(session, groups=('format',))
session.run('ruff', 'check', '--fix', *PY_PATHS)
session.run('ruff', 'format', *PY_PATHS)
# session.run(
Expand All @@ -99,7 +103,7 @@ def format_(session):
def lint(session):
"""Run linters in readonly mode."""
# We need to install 'doc' group because liccheck needs to inspect it.
pdm_install(session, 'doc', 'lint', 'full')
uv_install(session, groups=('doc', 'lint'), extras=('full',))
session.run('ruff', 'check', *PY_PATHS)
session.run('ruff', 'format', *PY_PATHS)
# session.run(
Expand All @@ -114,15 +118,12 @@ def lint(session):
session.run('pytest', 'test/static')
session.run('liccheck', '-s', 'pyproject.toml')

# Check if the lockfile is up to date
session.run('pdm', 'lock', '--check', external=True)


@nox.session(python=PYTHON_VERSIONS)
@nox.parametrize('extras', NOX_EXTRAS)
def unit(session, extras):
"""Run unit tests."""
pdm_install(session, 'test', *extras)
uv_install(session, groups=('test',), extras=tuple(extras))
args = ['--doctest-modules', '-n', 'auto']
if not skip_coverage(session.python):
args += ['--cov=b2sdk', '--cov-branch', '--cov-report=xml']
Expand All @@ -142,14 +143,14 @@ def unit(session, extras):
@nox.parametrize('extras', NOX_EXTRAS)
def integration(session, extras):
"""Run integration tests."""
pdm_install(session, 'test', *extras)
uv_install(session, groups=('test',), extras=tuple(extras))
session.run('pytest', '-s', *session.posargs, 'test/integration')


@nox.session(python=PYTHON_DEFAULT_VERSION)
def cleanup_old_buckets(session):
"""Remove buckets from previous test runs."""
pdm_install(session, 'test')
uv_install(session, groups=('test',))
session.run('python', '-m', 'test.integration.cleanup_buckets')


Expand All @@ -167,15 +168,15 @@ def test(session):
@nox.session
def cover(session):
"""Perform coverage analysis."""
pdm_install(session, 'test')
uv_install(session, groups=('test',))
session.run('coverage', 'report', '--fail-under=75', '--show-missing', '--skip-covered')
session.run('coverage', 'erase')


@nox.session(python=PYTHON_DEFAULT_VERSION)
def build(session):
"""Build the distribution."""
session.run('pdm', 'build', external=True)
session.run('uv', 'build', external=True)

# Set outputs for GitHub Actions
if CI:
Expand All @@ -191,7 +192,7 @@ def build(session):
@nox.session(python=PYTHON_DEFAULT_VERSION)
def doc(session):
"""Build the documentation."""
pdm_install(session, 'doc')
uv_install(session, groups=('doc',))
session.cd('doc')
sphinx_args = ['-b', 'html', '-T', '-W', 'source', 'build/html']
session.run('rm', '-rf', 'build', external=True)
Expand All @@ -216,7 +217,7 @@ def doc(session):
@nox.session
def doc_cover(session):
"""Perform coverage analysis for the documentation."""
pdm_install(session, 'doc')
uv_install(session, groups=('doc',))
session.cd('doc')
sphinx_args = ['-b', 'coverage', '-T', '-W', 'source', 'build/coverage']
report_file = 'build/coverage/python.txt'
Expand Down Expand Up @@ -253,7 +254,7 @@ def make_release_commit(session):
if current_branch != 'master':
session.log('WARNING: releasing from a branch different than master')

pdm_install(session, 'release')
uv_install(session, groups=('release',))
session.run('towncrier', 'build', '--yes', '--version', version)

session.log(
Expand Down
Loading
Loading