Skip to content

Commit 956ddbc

Browse files
authored
Migrates from pip to uv and adds dynamic versioning (#6156)
* feat: migrate from pip to uv for Python dependency management - Updated pyproject.toml with project metadata and dependencies - Modified CI/CD workflows to use uv instead of pip - Updated Dockerfile to install and use uv - Updated all documentation to use uv commands - Added MIGRATION_TO_UV.md guide - Created compile-requirements.sh script for uv - Updated .gitignore to exclude uv.lock This migration provides significant performance improvements while maintaining backward compatibility with existing requirements files. * pyproject toml * feat: finalize uv migration with working configuration - Simplified pyproject.toml to avoid conflicts with setup.py - Maintained hybrid approach for complex build system compatibility - Verified full installation and functionality with uv - Added verification script for testing uv setup - Updated migration guide with working configuration All tests pass: ✅ uv pip install -e ".[dev]" works correctly ✅ dispatch CLI command functional ✅ All 28 plugins discovered properly ✅ ~10x faster than pip installation * bumps py version * fix: update spacy from 3.8.5 to 3.8.7 - spacy==3.8.5 was yanked due to incorrect Python 3.13 support - Updated to spacy==3.8.7 which is the latest stable version - Recompiled requirements-base.txt with uv * feat: complete migration to uv with full pyproject.toml support 🚀 BREAKING CHANGE: Fully migrated from setup.py to pyproject.toml ## What's New ✅ Full modern uv support: uv add, uv remove, uv sync, uv lock ✅ Complete pyproject.toml configuration with all dependencies ✅ Lock file generation with uv.lock for reproducible builds ✅ All 28 plugins and entry points migrated ✅ Faster dependency management (~10x speedup) ## Migration Details - Moved setup.py → setup.py.bak (deprecated) - Added complete [project] table to pyproject.toml - All dependencies now in pyproject.toml instead of requirements files - Plugin entry points fully migrated - Updated verification script for modern workflow ## New Commands Available - uv sync --dev # Install all dependencies - uv add package-name # Add new dependency - uv remove package-name # Remove dependency - uv lock --upgrade # Update lock file ## Backward Compatibility - Legacy 'uv pip install -e .[dev]' still works - All existing functionality preserved - CI/CD workflows updated but compatible This completes the full modernization of Dispatch's Python packaging. * cleanup: remove obsolete config and requirements files 🧹 Major Cleanup: Complete transition to pyproject.toml ## Files Removed ❌ setup.cfg - moved configurations to pyproject.toml ❌ requirements-*.in/txt - dependencies now in pyproject.toml ❌ scripts/compile-requirements.sh - replaced by uv lock ❌ package.json/package-lock.json - accidentally committed files ## Configurations Migrated ✅ Moved pytest config from setup.cfg to pyproject.toml ✅ Moved coverage config from setup.cfg to pyproject.toml ✅ Black config already in pyproject.toml ## Modern Workflow - Dependencies: pyproject.toml (declarative) - Lock file: uv.lock (generated) - Testing: pytest with pyproject.toml config - Coverage: coverage with pyproject.toml config ## Benefits - 🗂️ Single source of truth: pyproject.toml - 🔒 Reproducible builds: uv.lock - 🧹 Cleaner repository: fewer config files - 📈 Modern standard: PEP 518/621 compliant This completes the full migration to modern Python packaging standards. * removes migration docs * improves docker related gh workflows * removes user from codeowners * fixes * disable trivy and sbom * fix * fix * playwright e2e tests fix * playwright e2e tests fix * wait for backend fix * playwright fixes * pyproject toml fixes * adds netflix dependency group * updates plugins path
1 parent 10dc63a commit 956ddbc

24 files changed

+647
-1258
lines changed

.devcontainer/postCreateCommand.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
pip install -e /workspaces/dispatch
1+
uv pip install -e /workspaces/dispatch
22
npm install --prefix /workspaces/dispatch/src/dispatch/static/dispatch
33

44
export LOG_LEVEL="ERROR"

.github/CODEOWNERS

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
kevgliss
2-
metroid-samus
32
mvilanova
43
whitdog47
54
wssheldon

.github/workflows/playwright.yml

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,32 +92,41 @@ jobs:
9292
- name: Set up Python 3.11
9393
uses: actions/setup-python@v5
9494
with:
95-
python-version: 3.11
95+
python-version: 3.11.11
9696
- uses: actions/setup-node@v4
9797
with:
98-
node-version: 18
98+
node-version-file: .nvmrc
9999
- uses: actions/cache@v4
100100
with:
101101
path: ~/.cache/pip
102102
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
103103
restore-keys: |
104104
${{ runner.os }}-pip-
105-
- name: Install python dependencies
105+
- name: Install uv
106+
run: |
107+
curl -LsSf https://astral.sh/uv/install.sh | sh
108+
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
109+
- name: Install dependencies
106110
run: |
107111
export DISPATCH_LIGHT_BUILD=1
108-
python -m pip install --upgrade pip
109-
pip install psycopg[binary]
110-
pip install -e ".[dev]"
112+
uv venv
113+
source .venv/bin/activate
114+
uv pip install psycopg[binary]
115+
uv pip install -e ".[dev]"
111116
- name: Install npm dependencies
112117
run: |
113118
npm ci -D --prefix src/dispatch/static/dispatch
114-
npm install -D @playwright/test
119+
npm ci
115120
- name: Install playwright browsers
116121
run: npx playwright install --with-deps chromium
117122
- name: Setup sample database
118-
run: dispatch database restore --dump-file data/dispatch-sample-data.dump --skip-check && dispatch database upgrade
123+
run: |
124+
source .venv/bin/activate
125+
dispatch database restore --dump-file data/dispatch-sample-data.dump --skip-check && dispatch database upgrade
119126
- name: Run tests
120-
run: npx playwright test --project=chromium --shard=${{ matrix.shard }}/4
127+
run: |
128+
source .venv/bin/activate
129+
npx playwright test --project=chromium --shard=${{ matrix.shard }}/4
121130
- uses: actions/upload-artifact@v4
122131
if: always()
123132
with:
Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,57 @@
11
name: Test image build
22

3-
on: pull_request
3+
"on":
4+
pull_request:
5+
paths:
6+
- "Dockerfile"
7+
- "docker/Dockerfile"
8+
- "src/**"
9+
- "pyproject.toml"
10+
- ".github/workflows/publish-image-test.yml"
411

512
jobs:
613
build_image:
7-
name: Build Docker image
14+
name: Build and test Docker image
815
runs-on: ubuntu-latest
916
steps:
1017
- name: Check out the repo
1118
uses: actions/checkout@v4
12-
- name: Build without push
13-
uses: docker/build-push-action@v1
19+
20+
- name: Set up Docker Buildx
21+
uses: docker/setup-buildx-action@v3
22+
23+
- name: Extract metadata
24+
id: meta
25+
uses: docker/metadata-action@v5
26+
with:
27+
images: dispatch-test
28+
tags: |
29+
type=ref,event=pr,prefix=pr-
30+
type=sha,prefix=sha-
31+
32+
- name: Build Docker image
33+
uses: docker/build-push-action@v6
1434
with:
35+
context: .
36+
file: ./Dockerfile
1537
push: false
38+
tags: ${{ steps.meta.outputs.tags }}
39+
labels: ${{ steps.meta.outputs.labels }}
40+
cache-from: type=gha
41+
cache-to: type=gha,mode=max
42+
build-args: |
43+
SOURCE_COMMIT=${{ github.sha }}
44+
VITE_DISPATCH_COMMIT_HASH=${{ github.sha }}
45+
46+
# - name: Run Trivy vulnerability scanner
47+
# uses: aquasecurity/trivy-action@master
48+
# with:
49+
# image-ref: "dispatch-test:${{ github.event.pull_request.head.sha || github.sha }}"
50+
# format: "sarif"
51+
# output: "trivy-results.sarif"
52+
53+
# - name: Upload Trivy scan results to GitHub Security tab
54+
# uses: github/codeql-action/upload-sarif@v3
55+
# if: always()
56+
# with:
57+
# sarif_file: "trivy-results.sarif"

.github/workflows/publish-image.yml

Lines changed: 93 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,105 @@
11
name: Publish Docker image
2-
on:
2+
3+
"on":
34
release:
45
types: [published]
6+
workflow_dispatch:
7+
inputs:
8+
tag:
9+
description: "Tag to build and push"
10+
required: true
11+
default: "latest"
12+
13+
env:
14+
REGISTRY_GITHUB: ghcr.io
15+
REGISTRY_DOCKERHUB: docker.io
16+
IMAGE_NAME: netflix/dispatch
17+
518
jobs:
619
push_to_registry:
7-
name: Push Docker image to GitHub Packages
20+
name: Build and push Docker image
821
runs-on: ubuntu-latest
22+
permissions:
23+
contents: read
24+
packages: write
25+
security-events: write
926
steps:
1027
- name: Check out the repo
1128
uses: actions/checkout@v4
12-
- name: Push to GitHub Packages
13-
uses: docker/build-push-action@v1
29+
30+
- name: Set up QEMU
31+
uses: docker/setup-qemu-action@v3
32+
33+
- name: Set up Docker Buildx
34+
uses: docker/setup-buildx-action@v3
35+
36+
- name: Log in to GitHub Container Registry
37+
uses: docker/login-action@v3
1438
with:
39+
registry: ${{ env.REGISTRY_GITHUB }}
1540
username: ${{ github.actor }}
1641
password: ${{ secrets.GITHUB_TOKEN }}
17-
registry: docker.pkg.github.com
18-
repository: netflix/dispatch/dispatch-image
19-
tag_with_ref: true
42+
43+
- name: Log in to Docker Hub
44+
uses: docker/login-action@v3
45+
continue-on-error: true
46+
with:
47+
registry: ${{ env.REGISTRY_DOCKERHUB }}
48+
username: ${{ secrets.DOCKERHUB_USERNAME }}
49+
password: ${{ secrets.DOCKERHUB_TOKEN }}
50+
51+
- name: Extract metadata
52+
id: meta
53+
uses: docker/metadata-action@v5
54+
with:
55+
images: |
56+
${{ env.REGISTRY_GITHUB }}/${{ env.IMAGE_NAME }}
57+
${{ env.REGISTRY_DOCKERHUB }}/${{ env.IMAGE_NAME }}
58+
tags: |
59+
type=ref,event=tag
60+
type=ref,event=branch
61+
type=semver,pattern={{version}}
62+
type=semver,pattern={{major}}.{{minor}}
63+
type=semver,pattern={{major}}
64+
type=raw,value=latest,enable={{is_default_branch}}
65+
66+
- name: Build and push Docker image
67+
uses: docker/build-push-action@v6
68+
with:
69+
context: .
70+
file: ./Dockerfile
71+
platforms: linux/amd64,linux/arm64
72+
push: true
73+
tags: ${{ steps.meta.outputs.tags }}
74+
labels: ${{ steps.meta.outputs.labels }}
75+
cache-from: type=gha
76+
cache-to: type=gha,mode=max
77+
build-args: |
78+
SOURCE_COMMIT=${{ github.sha }}
79+
VITE_DISPATCH_COMMIT_HASH=${{ github.sha }}
80+
81+
# - name: Run Trivy vulnerability scanner
82+
# uses: aquasecurity/trivy-action@master
83+
# with:
84+
# image-ref: ${{ env.REGISTRY_GITHUB }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
85+
# format: "sarif"
86+
# output: "trivy-results.sarif"
87+
88+
# - name: Upload Trivy scan results to GitHub Security tab
89+
# uses: github/codeql-action/upload-sarif@v3
90+
# if: always()
91+
# with:
92+
# sarif_file: "trivy-results.sarif"
93+
94+
# - name: Generate SBOM
95+
# uses: anchore/sbom-action@v0
96+
# with:
97+
# image: ${{ env.REGISTRY_GITHUB }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
98+
# format: spdx-json
99+
# output-file: sbom.spdx.json
100+
101+
# - name: Upload SBOM
102+
# uses: actions/upload-artifact@v4
103+
# with:
104+
# name: sbom
105+
# path: sbom.spdx.json

.github/workflows/python.yml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,25 +27,32 @@ jobs:
2727
- name: Set up Python 3.11
2828
uses: actions/setup-python@v5
2929
with:
30-
python-version: 3.11.2
30+
python-version: 3.11.11
3131
- uses: actions/cache@v4
3232
with:
3333
path: ~/.cache/pip
3434
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
3535
restore-keys: |
3636
${{ runner.os }}-pip-
37+
- name: Install uv
38+
run: |
39+
curl -LsSf https://astral.sh/uv/install.sh | sh
40+
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
3741
- name: Install python dependencies
3842
run: |
3943
export DISPATCH_LIGHT_BUILD=1
40-
python -m pip install --upgrade pip
41-
pip install -e ".[dev]"
44+
uv venv
45+
source .venv/bin/activate
46+
uv pip install -e ".[dev]"
4247
- name: "Lint with ruff"
4348
run: |
49+
source .venv/bin/activate
4450
ruff check src tests
4551
ruff format src tests
4652
- name: Test with pytest
4753
run: |
48-
pip install pytest-cov
54+
source .venv/bin/activate
55+
uv pip install pytest-cov
4956
pytest --junitxml=junit/test-results.xml --cov=dispatch --cov-report=json:coverage.json --cov-report=xml --cov-report=html
5057
- name: Coverage per file
5158
# All modified files should meet the minimum code coverage requirement.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ ipython_config.py
133133
!data/.env
134134
.venv
135135
env/
136+
# uv
137+
uv.lock
136138
venv/
137139
ENV/
138140
env.bak/

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Quick Start:
22
#
3-
# pip install pre-commit
3+
# uv pip install pre-commit
44
# pre-commit install && pre-commit install -t pre-push
55
# pre-commit run --all-files
66
#
@@ -10,7 +10,7 @@
1010
fail_fast: false
1111

1212
default_language_version:
13-
python: python3.11.2
13+
python: python3.11.11
1414

1515
repos:
1616
- repo: https://github.com/astral-sh/ruff-pre-commit

docker/Dockerfile

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
1515
# Needed for fetching stuff
1616
ca-certificates \
1717
wget \
18+
curl \
1819
&& rm -rf /var/lib/apt/lists/*
1920

21+
# Install uv for building
22+
RUN curl -LsSf https://astral.sh/uv/0.4.17/install.sh | sh && \
23+
mv /root/.cargo/bin/uv /usr/local/bin/
24+
2025
RUN wget --quiet -O - https://deb.nodesource.com/setup_20.x | bash - \
2126
&& apt-get install -y nodejs --no-install-recommends
2227

@@ -51,7 +56,7 @@ COPY . /usr/src/dispatch/
5156
RUN YARN_CACHE_FOLDER="$(mktemp -d)" \
5257
&& export YARN_CACHE_FOLDER \
5358
&& pushd /usr/src/dispatch \
54-
&& python setup.py bdist_wheel \
59+
&& uv build \
5560
&& rm -r "$YARN_CACHE_FOLDER" \
5661
&& mv /usr/src/dispatch/dist /dist
5762

@@ -81,9 +86,13 @@ ENV PIP_NO_CACHE_DIR=off \
8186
RUN apt-get update && apt-get install -y --no-install-recommends \
8287
# Needed for fetching stuff
8388
ca-certificates \
84-
wget gnupg \
89+
wget gnupg curl \
8590
&& rm -rf /var/lib/apt/lists/*
8691

92+
# Install uv
93+
RUN curl -LsSf https://astral.sh/uv/0.4.17/install.sh | sh && \
94+
mv /root/.cargo/bin/uv /usr/local/bin/
95+
8796
RUN echo "deb http://apt.postgresql.org/pub/repos/apt bullseye-pgdg main" > /etc/apt/sources.list.d/pgdg.list \
8897
&& wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
8998

@@ -94,7 +103,7 @@ RUN buildDeps="" \
94103
&& apt-get update \
95104
&& apt-get install -y --no-install-recommends "$buildDeps" \
96105
# remove internal index when internal plugins are separated
97-
&& pip install -U /tmp/dist/*.whl \
106+
&& uv pip install --system -U /tmp/dist/*.whl \
98107
&& apt-get purge -y --auto-remove "$buildDeps" \
99108
# We install run-time dependencies strictly after
100109
# build dependencies to prevent accidental collusion.
@@ -106,7 +115,7 @@ RUN buildDeps="" \
106115
&& rm -rf /var/lib/apt/lists/* \
107116
# mjml has to be installed differently here because
108117
# after node 14, docker will install npm files at the
109-
# root directoy and fail, so we have to create a new
118+
# root directory and fail, so we have to create a new
110119
# directory and use it for the install then copy the
111120
# files to the root directory to maintain backwards
112121
# compatibility for email generation

docs/docs/administration/contributing/environment.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ This guide assumes you're using an OS of the Linux/Unix variant \(Ubuntu/OS X\)
1212
Install Dispatch with PIP:
1313

1414
```bash
15-
> DISPATCH_LIGHT_BUILD=1 pip install -e .[dev]
15+
> DISPATCH_LIGHT_BUILD=1 uv pip install -e .[dev]
1616
```
1717

1818
Run dev server:
@@ -55,7 +55,7 @@ Create a new virtualenv just for Dispatch:
5555
Install Dispatch with pip:
5656

5757
```bash
58-
> pip install -e /path/to/dispatch
58+
> uv pip install -e /path/to/dispatch
5959
```
6060

6161
Test it by seeing if the `dispatch` command is in your path:

0 commit comments

Comments
 (0)