Skip to content

Commit c28cdb0

Browse files
authored
Merge pull request #31 from openscm/uv-build
Switch to uv build backend
2 parents ce53f4c + ef500bb commit c28cdb0

File tree

11 files changed

+2271
-2209
lines changed

11 files changed

+2271
-2209
lines changed

.github/actions/setup/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ runs:
2020
id: setup-uv
2121
uses: astral-sh/setup-uv@v4
2222
with:
23-
version: "0.5.21"
23+
version: "0.8.8"
2424
python-version: ${{ inputs.python-version }}
2525
- name: Install dependencies
2626
shell: bash

.github/workflows/bump.yaml

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
11
name: Bump version
2-
# For the time being, we still do this with pdm.
3-
# Honestly, it doesn't really matter,
4-
# but one day uv will have a bump command too and we can switch to that.
5-
# Relevant issue in uv: https://github.com/astral-sh/uv/issues/6298
62

73
on:
84
workflow_dispatch:
95
inputs:
106
bump_rule:
117
type: choice
12-
description: How to bump the project's version (see https://github.com/carstencodes/pdm-bump#usage)
8+
description: How to bump the project's version (see https://docs.astral.sh/uv/reference/cli/#uv-version)
139
options:
14-
- no-pre-release
15-
# no micro because we always sit on a pre-release in main,
16-
# so we would always use no-pre-release instead of micro
17-
# - micro
10+
- stable
11+
- patch
1812
- minor
1913
- major
20-
- "pre-release --pre alpha"
21-
- "pre-release --pre beta"
22-
- "pre-release --pre release-candidate"
14+
- alpha
15+
- beta
16+
- rc
17+
- post
18+
- dev
2319
required: true
2420

2521
jobs:
@@ -40,15 +36,6 @@ jobs:
4036
fetch-depth: 0
4137
token: "${{ secrets.PERSONAL_ACCESS_TOKEN }}"
4238

43-
- name: Setup PDM
44-
uses: pdm-project/setup-pdm@v4.1
45-
with:
46-
python-version: ${{ matrix.python-version }}
47-
48-
- name: Install pdm-bump
49-
run: |
50-
pdm self add pdm-bump
51-
5239
- uses: ./.github/actions/setup
5340
with:
5441
python-version: ${{ matrix.python-version }}
@@ -63,7 +50,7 @@ jobs:
6350
echo "Bumping from version $BASE_VERSION"
6451
6552
# Bump
66-
pdm bump ${{ github.event.inputs.bump_rule }}
53+
uv version --bump ${{ github.event.inputs.bump_rule }}
6754
6855
NEW_VERSION=`sed -ne 's/^version = "\([0-9\.a]*\)"/\1/p' pyproject.toml`
6956
echo "Bumping to version $NEW_VERSION"
@@ -81,7 +68,7 @@ jobs:
8168
BASE_VERSION=`sed -ne 's/^version = "\([0-9\.a]*\)"/\1/p' pyproject.toml`
8269
8370
# Bump to pre-release of next version
84-
pdm bump pre-release --pre alpha
71+
uv version --bump post
8572
8673
NEW_VERSION=`sed -ne 's/^version = "\([0-9\.a]*\)"/\1/p' pyproject.toml`
8774
echo "Bumping version $BASE_VERSION > $NEW_VERSION"

.github/workflows/ci.yaml

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ jobs:
148148
id: setup-uv
149149
uses: astral-sh/setup-uv@v4
150150
with:
151-
version: "0.5.21"
151+
version: "0.8.8"
152152
python-version: ${{ matrix.python-version }}
153153
- name: Create venv
154154
run: |
@@ -267,21 +267,15 @@ jobs:
267267
id: setup-uv
268268
uses: astral-sh/setup-uv@v4
269269
with:
270-
version: "0.5.21"
270+
version: "0.8.8"
271271
python-version: ${{ matrix.python-version }}
272-
- name: Setup PDM
273-
uses: pdm-project/setup-pdm@v4.1
274-
with:
275-
python-version: ${{ matrix.python-version }}
276-
- name: Generate pdm.lock
277-
# Required for building the locked version of the package
278-
# with pdm-build-locked (see pyproject.toml)
279-
run: |
280-
pdm lock --group :all --strategy inherit_metadata --python="<3.13"
281-
pdm lock --group :all --python=">=3.13" --append
282272
- name: Build package
283273
run: |
274+
uv run python scripts/add-locked-targets-to-pyproject-toml.py
275+
cat pyproject.toml
284276
uv build
277+
# Just in case, undo the changes to `pyproject.toml`
278+
git restore --staged . && git restore .
285279
- name: Check build
286280
run: |
287281
tar -tvf dist/pandas_openscm-*.tar.gz --wildcards '*pandas_openscm/py.typed'

.github/workflows/deploy.yaml

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,12 @@ jobs:
3232
id: setup-uv
3333
uses: astral-sh/setup-uv@v4
3434
with:
35-
version: "0.5.21"
35+
version: "0.8.8"
3636
python-version: ${{ matrix.python-version }}
37-
- name: Setup PDM
38-
uses: pdm-project/setup-pdm@v4.1
39-
with:
40-
python-version: ${{ matrix.python-version }}
41-
- name: Generate pdm.lock
42-
# Required for building the locked version of the package
43-
# with pdm-build-locked (see pyproject.toml)
44-
run: |
45-
pdm lock --group :all --strategy inherit_metadata --python="<3.13"
46-
pdm lock --group :all --python=">=3.13" --append
4737
- name: Publish to PyPI
4838
run: |
39+
uv run python scripts/add-locked-targets-to-pyproject-toml.py
4940
uv build
5041
uv publish
42+
# Just in case, undo the changes to `pyproject.toml`
43+
git restore --staged . && git restore .

.github/workflows/release.yaml

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,18 @@ jobs:
2525
id: setup-uv
2626
uses: astral-sh/setup-uv@v4
2727
with:
28-
version: "0.5.21"
28+
version: "0.8.8"
2929
python-version: ${{ matrix.python-version }}
30-
- name: Setup PDM
31-
uses: pdm-project/setup-pdm@v4.1
32-
with:
33-
python-version: ${{ matrix.python-version }}
34-
- name: Generate pdm.lock
35-
# Required for building the locked version of the package
36-
# with pdm-build-locked (see pyproject.toml)
37-
run: |
38-
pdm lock --group :all --strategy inherit_metadata --python="<3.13"
39-
pdm lock --group :all --python=">=3.13" --append
4030
- name: Add version to environment
4131
run: |
4232
PROJECT_VERSION=`sed -ne 's/^version = "\([0-9\.a]*\)"/\1/p' pyproject.toml`
4333
echo "PROJECT_VERSION=$PROJECT_VERSION" >> $GITHUB_ENV
4434
- name: Build package for PyPI
4535
run: |
36+
uv run python scripts/add-locked-targets-to-pyproject-toml.py
4637
uv build
38+
# Just in case, undo the changes to `pyproject.toml`
39+
git restore --staged . && git restore .
4740
- name: Generate Release Notes
4841
run: |
4942
echo "" >> ".github/release_template.md"

.github/workflows/test-upstream-latest.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
id: setup-uv
3737
uses: astral-sh/setup-uv@v4
3838
with:
39-
version: "0.5.21"
39+
version: "0.8.8"
4040
python-version: ${{ matrix.python-version }}
4141
# Often you need a step like this for e.g. numpy, scipy, pandas
4242
- name: Setup compilation dependencies

changelog/31.trivial.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Switched to using uv for the build backend. Updated dev docs accordingly, including describing the purpose of `scripts/add-locked-targets-to-pyproject-toml.py`.

docs/development.md

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,16 @@ should change depending on the updates to the code base.
4848
Releasing is semi-automated via a CI job.
4949
The CI job requires the type of version bump
5050
that will be performed to be manually specified.
51-
See the pdm-bump docs for the
52-
[list of available bump rules](https://github.com/carstencodes/pdm-bump#usage).
51+
See the `uv version` docs (specifically the `--bump` flag) for the
52+
[list of available bump rules](https://docs.astral.sh/uv/reference/cli/#uv-version).
5353

5454
### Standard process
5555

5656
The steps required are the following:
5757

5858
1. Bump the version: manually trigger the "bump" workflow from the main branch
5959
(see here: [bump workflow](https://github.com/openscm/pandas-openscm/actions/workflows/bump.yaml)).
60-
A valid "bump_rule" (see [pdm-bump's docs](https://github.com/carstencodes/pdm-bump#usage))
60+
A valid "bump_rule" (see [uv's docs](https://docs.astral.sh/uv/reference/cli/#uv-version))
6161
will need to be specified.
6262
This will then trigger a draft release.
6363

@@ -87,12 +87,10 @@ The steps required are the following:
8787

8888
#### Further details
8989

90-
We use [pdm](https://pdm-project.org/en/latest/) for building our project,
91-
while [uv figures out how it wants to support building](https://github.com/astral-sh/uv/issues/3957).
92-
This gives us the added benefit that we can use
93-
[pdm-build-locked](https://pdm-build-locked.readthedocs.io/en/stable/)
94-
to build locked versions of our package.
95-
It is for these reasons that we create a `pdm.lock` file
90+
We use [uv's build backend](https://docs.astral.sh/uv/concepts/build-backend) for building our project
91+
and `scripts/add-locked-targets-to-pyproject-toml.py`
92+
to provide locked extra groups for our package.
93+
Including locked extra groups is why we run `scripts/add-locked-targets-to-pyproject-toml.py`
9694
before any step related to building the package in the CI.
9795

9896
## Read the Docs

pyproject.toml

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ dev = [
9090
"types-tqdm>=4.67.0.20241221",
9191
"tomli>=2.2.1",
9292
"typer>=0.15.2",
93+
"tomli-w>=1.2.0",
9394
]
9495
docs = [
9596
# Key dependencies
@@ -154,16 +155,11 @@ all-dev = [
154155
]
155156

156157
[build-system]
157-
requires = [
158-
"pdm-backend",
159-
"pdm-build-locked",
160-
]
161-
build-backend = "pdm.backend"
158+
requires = ["uv_build>=0.8.7,<0.9.0"]
159+
build-backend = "uv_build"
162160

163-
[tool.pdm]
164-
[tool.pdm.build]
165-
locked = true
166-
includes = [
161+
[tool.uv.build-backend]
162+
source-include = [
167163
"src/pandas_openscm",
168164
"LICENCE",
169165
]
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
"""
2+
Add locked targets to `pyproject.toml`
3+
4+
This adds a "locked" target
5+
plus a "<option>-locked" target
6+
for each optional dependency group.
7+
8+
Only works with uv.
9+
"""
10+
11+
from __future__ import annotations
12+
13+
import copy
14+
import subprocess
15+
from pathlib import Path
16+
17+
import tomli_w
18+
import tomllib
19+
20+
21+
def parse_uv_export_output(raw: str) -> list[str]:
22+
"""
23+
Parse `uv export` output
24+
25+
Parameters
26+
----------
27+
raw
28+
Raw output string
29+
30+
Returns
31+
-------
32+
:
33+
Parsed dependencies
34+
"""
35+
raw_split = raw.splitlines()
36+
deps = [v for v in raw_split if not v.strip().startswith("#")]
37+
38+
return deps
39+
40+
41+
def main():
42+
"""
43+
Update the `pyproject.toml` file with locked targets
44+
"""
45+
project_root = Path(__file__).parents[1]
46+
pyproject_file = project_root / "pyproject.toml"
47+
pyproject_file_out = pyproject_file
48+
# Handy for testing
49+
# pyproject_file_out = project_root / "pyproject.toml.injected"
50+
51+
with open(pyproject_file, "rb") as fh:
52+
pyproject_in = tomllib.load(fh)
53+
54+
pyproject_out = copy.deepcopy(pyproject_in)
55+
for optional_dep, uv_export_flags in (
56+
("locked", ()),
57+
*(
58+
(f"{extra}-locked", ("--extra", extra))
59+
for extra in pyproject_in["project"]["optional-dependencies"]
60+
),
61+
):
62+
uv_export_res = subprocess.run( # noqa: S603
63+
(
64+
"uv",
65+
"export",
66+
"--no-hashes",
67+
"--no-annotate",
68+
"--no-emit-project",
69+
"--no-dev",
70+
*uv_export_flags,
71+
),
72+
check=True,
73+
stdout=subprocess.PIPE,
74+
)
75+
76+
parsed_deps = parse_uv_export_output(uv_export_res.stdout.decode())
77+
78+
pyproject_out["project"]["optional-dependencies"][optional_dep] = parsed_deps
79+
80+
with open(pyproject_file_out, "wb") as f:
81+
tomli_w.dump(pyproject_out, f)
82+
83+
84+
if __name__ == "__main__":
85+
main()

0 commit comments

Comments
 (0)