Skip to content

Commit e4420c5

Browse files
authored
chore: release process upgrades (#39)
* chore: release process upgrades * chore: dev dep group is not an extra * chore: drop 3.9 support * chore: upgrade pyarrow dep
1 parent 4fe52ca commit e4420c5

File tree

10 files changed

+234
-340
lines changed

10 files changed

+234
-340
lines changed

.github/workflows/CI.yml

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,79 @@ name: CI
33
on:
44
push:
55
branches:
6+
- main
67
- master
8+
tags:
9+
- "*"
710
pull_request:
811
workflow_dispatch:
12+
workflow_run:
13+
workflows: ["Deploy Release"]
14+
types:
15+
- completed
16+
17+
permissions:
18+
contents: read
919

1020
jobs:
11-
linux_tests:
21+
check-commit:
22+
runs-on: ubuntu-latest
23+
if: >
24+
(
25+
(
26+
(github.event_name == 'push')
27+
|| (github.event_name == 'pull_request' && github.event.pull_request.user.login == 'lmmx')
28+
)
29+
&&
30+
(
31+
startsWith(github.event.head_commit.message, 'chore(release)') ||
32+
contains(github.event.head_commit.message, 'cibuildwheel')
33+
)
34+
)
35+
|| (github.event_name == 'workflow_dispatch')
36+
|| (github.event_name == 'workflow_run')
37+
steps:
38+
- name: Confirm commit message matched
39+
run: echo "Commit message matched the condition."
40+
41+
build:
42+
needs: [check-commit]
43+
runs-on: ubuntu-latest
44+
steps:
45+
- uses: actions/checkout@v4
46+
47+
- name: Install uv
48+
uses: astral-sh/setup-uv@v7
49+
50+
- name: Build package
51+
run: uv build
52+
53+
- name: Upload wheels
54+
uses: actions/upload-artifact@v4
55+
with:
56+
name: wheels-sdist
57+
path: dist
58+
59+
release:
60+
name: Release
61+
environment: pypi
1262
runs-on: ubuntu-latest
13-
strategy:
14-
matrix:
15-
target: [x86_64]
63+
if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_run' }}
64+
needs: [build]
65+
permissions:
66+
id-token: write
67+
contents: write
68+
attestations: write
1669
steps:
17-
- uses: actions/checkout@v3
18-
- name: "Install uv"
19-
uses: astral-sh/setup-uv@v5
70+
- uses: actions/download-artifact@v4
71+
72+
- name: Generate artifact attestation
73+
uses: actions/attest-build-provenance@v1
74+
with:
75+
subject-path: "wheels-*/*"
76+
77+
- name: Publish to PyPI
78+
if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_run' }}
79+
uses: pypa/gh-action-pypi-publish@release/v1
2080
with:
21-
version: "0.6.8"
22-
- name: Install the project
23-
run: uv sync
24-
- run: uv run pytest tests -s
81+
packages-dir: wheels-sdist/

.github/workflows/deploy.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Deploy Release
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
deploy-release:
8+
name: Run just release
9+
runs-on: ubuntu-latest
10+
permissions:
11+
contents: write
12+
13+
steps:
14+
- name: Checkout repository
15+
uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 0
18+
persist-credentials: true
19+
20+
- name: Install uv
21+
uses: astral-sh/setup-uv@v7
22+
23+
- name: Install just
24+
uses: taiki-e/install-action@64adfd9e935fa438859b9e080fd026720b2ba070 # tag=just
25+
with:
26+
27+
28+
- name: Configure git identity
29+
run: |
30+
git config user.name "github-actions[bot]"
31+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
32+
33+
# Bump version, commit changes, tag as the version, and push both
34+
# commit and tag (pushing the latter triggers package release)
35+
- name: Run just release
36+
run: just release

.github/workflows/test.yml

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
workflow_dispatch:
9+
10+
concurrency:
11+
group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.sha }}
12+
cancel-in-progress: true
13+
14+
jobs:
15+
get-python-versions:
16+
runs-on: ubuntu-latest
17+
timeout-minutes: 5
18+
outputs:
19+
python-versions: ${{ steps.get-versions.outputs.python-versions }}
20+
steps:
21+
- uses: actions/checkout@v4
22+
23+
- name: Install uv
24+
uses: astral-sh/setup-uv@v7
25+
26+
- name: Get Python versions from pyproject.toml
27+
id: get-versions
28+
run: |
29+
set -euo pipefail
30+
MIN_VERSION=$(uvx --from=toml-cli toml get --toml-path=pyproject.toml project.requires-python | sed 's/>=//;s/"//g')
31+
32+
LIST=$(uv python list --all-versions --output-format json)
33+
34+
CPYTHON_VERSIONS=$(echo "$LIST" | jq -c --arg min "$MIN_VERSION" '
35+
($min | split(".") | {major: .[0]|tonumber, minor: .[1]|tonumber}) as $minv |
36+
[.[] | {v:.version_parts, t:.variant, impl:.implementation}]
37+
| unique_by([.v.minor,.t])
38+
| map(select(
39+
(.impl == "cpython") and
40+
(.v.major == 3) and
41+
(.v.minor >= $minv.minor)
42+
))
43+
| map(select(.t != "freethreaded")) # Delete this line to include FT variants
44+
| map("\(.v.major).\(.v.minor)\(if .t=="freethreaded" then "t" else "" end)")')
45+
46+
# PYPY_VERSIONS=$(echo "$LIST" | jq -c --arg min "$MIN_VERSION" '
47+
# ($min | split(".") | {major: .[0]|tonumber, minor: .[1]|tonumber}) as $minv |
48+
# [.[] | {v:.version_parts, t:.variant, impl:.implementation}]
49+
# | unique_by([.v.minor,.impl])
50+
# | map(select(
51+
# (.impl == "pypy") and
52+
# (.v.major == 3) and
53+
# (.v.minor >= $minv.minor)
54+
# ))
55+
# | map("pypy-\(.v.major).\(.v.minor)")')
56+
57+
# versions=$(jq -nc --argjson a "$CPYTHON_VERSIONS" --argjson b "$PYPY_VERSIONS" '$a + $b')
58+
versions=$(jq -nc --argjson a "$CPYTHON_VERSIONS" '$a')
59+
60+
echo "python-versions=$versions" >> $GITHUB_OUTPUT
61+
62+
test:
63+
needs: get-python-versions
64+
runs-on: ubuntu-latest
65+
timeout-minutes: 10
66+
strategy:
67+
fail-fast: false
68+
matrix:
69+
python-version: ${{ fromJson(needs.get-python-versions.outputs.python-versions) }}
70+
steps:
71+
- uses: actions/checkout@v4
72+
73+
- name: Install uv
74+
uses: astral-sh/setup-uv@v7
75+
with:
76+
python-version: ${{ matrix.python-version }}
77+
78+
- name: Install dependencies
79+
run: uv sync --group test
80+
81+
- name: Run tests
82+
run: $(uv python find) -m pytest

.just/py-release.just

Lines changed: 0 additions & 83 deletions
This file was deleted.

.just/ship.just

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Release a new version, pass --help for options to `uv version --bump`
2+
release bump_level="patch":
3+
#!/usr/bin/env -S echo-comment --shell-flags="-e" --color bright-green
4+
5+
## Exit early if help was requested
6+
if [[ "{{ bump_level }}" == "--help" ]]; then
7+
uv version --help
8+
exit 0
9+
fi
10+
11+
# 📈 Bump the version in pyproject.toml (patch/minor/major: {{ bump_level }})
12+
uv version --bump {{ bump_level }}
13+
14+
# 📦 Stage all changes (including the version bump)
15+
git add --all
16+
17+
# 🔄 Create a temporary commit to capture the new version
18+
git commit -m "chore(temp): version check"
19+
20+
# ✂️ Extract the new version number that was just set, undo the commit
21+
new_version=$(uv version --short)
22+
git reset --soft HEAD~1
23+
24+
# ✅ Stage everything again and create the real release commit
25+
git add --all
26+
git commit -m "chore(release): bump 🐍 -> v$new_version"
27+
28+
# 🏷️ Create the git tag for this release
29+
git tag -a "$new_version" -m "Release $new_version"
30+
31+
branch_name=$(git rev-parse --abbrev-ref HEAD);
32+
# 🚀 Push the release commit to $branch_name
33+
git push origin $branch_name
34+
35+
# 🚀 Push the commit tag to the remote (will trigger PyPI release via Trusted Publishing)
36+
git push origin "$new_version"

.just/test.just

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
test *args:
2+
$(uv python find) -m pytest {{args}}

0 commit comments

Comments
 (0)