Skip to content

Commit d93d1db

Browse files
committed
Squashed commits 1-50 for UV migration PR
Added imports for referencing added --dev back referencing
1 parent bd8f6eb commit d93d1db

File tree

21 files changed

+4517
-96
lines changed

21 files changed

+4517
-96
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: 'Cache UV Packages'
2+
description: 'Caches UV package cache directory for faster dependency installation'
3+
inputs:
4+
lockfile-path:
5+
description: 'Path to uv.lock file (relative to repository root)'
6+
required: false
7+
default: ''
8+
runs:
9+
using: 'composite'
10+
steps:
11+
- name: Cache UV packages
12+
if: inputs.lockfile-path != ''
13+
uses: actions/cache@v4
14+
id: uv-cache
15+
with:
16+
path: |
17+
~/.cache/uv
18+
key: ${{ runner.os }}-uv-${{ hashFiles(inputs.lockfile-path) }}
19+
restore-keys: |
20+
${{ runner.os }}-uv-
21+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: 'Install UV'
2+
description: 'Installs uv package manager manually to avoid setup-uv action post-job cleanup issues'
3+
inputs:
4+
version:
5+
description: 'UV version to install (default: latest)'
6+
required: false
7+
default: ''
8+
runs:
9+
using: 'composite'
10+
steps:
11+
- name: Install uv
12+
shell: bash
13+
run: |
14+
# Install uv manually to avoid setup-uv's post-job cleanup issues
15+
# This gives us full control and avoids the cache directory cleanup bug
16+
if [ -n "${{ inputs.version }}" ]; then
17+
curl -LsSf https://astral.sh/uv/install.sh | UV_VERSION="${{ inputs.version }}" sh
18+
else
19+
curl -LsSf https://astral.sh/uv/install.sh | sh
20+
fi
21+
# Add uv to PATH - $GITHUB_PATH works the same on all platforms
22+
# This will be available in subsequent steps
23+
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
24+

.github/actions/python/setup/action.yaml

Lines changed: 90 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,106 @@ inputs:
88
description: "What Python version to use to create the project's virtual environment"
99
required: false
1010
default: "false"
11+
install-system-deps:
12+
description: 'Whether to install system dependencies (libsystemd-dev on Linux)'
13+
required: false
14+
default: 'true'
15+
install-dev-deps:
16+
description: 'Whether to install dev optional dependencies (UV projects only: --extra dev)'
17+
required: false
18+
default: 'true'
19+
outputs:
20+
start-time:
21+
description: 'Start time of the setup process (Unix timestamp)'
22+
value: ${{ steps.setup-env.outputs.start-time }}
23+
duration:
24+
description: 'Duration of the setup process in seconds'
25+
value: ${{ steps.setup-env.outputs.duration }}
1126
runs:
1227
using: 'composite'
1328
steps:
1429
- shell: bash
30+
if: inputs.install-system-deps == 'true'
1531
run: |
1632
if [[ "${OSTYPE}" =~ "linux" ]]; then
1733
# WORKAROUND: Remove microsoft debian repo due to https://github.com/microsoft/linux-package-repositories/issues/130. Remove line below after it is resolved
1834
sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
1935
sudo apt-get update
2036
sudo apt-get install -y --no-install-recommends libsystemd-dev
2137
fi
22-
- name: Set the OT_PYTHON env variable
23-
shell: bash
24-
run: echo "OT_PYTHON=$(which python)" >> $GITHUB_ENV
25-
- name: If provided set the OT_VIRTUALENV_VERSION env variable
26-
shell : bash
27-
if: ${{ inputs.python-version != 'false' }}
28-
run: echo "OT_VIRTUALENV_VERSION=${{ inputs.python-version }}" >> $GITHUB_ENV
2938
- shell: bash
3039
run: npm install --global [email protected]
31-
- shell: bash
32-
run: $OT_PYTHON -m pip install --upgrade pip
33-
- shell: bash
34-
run: $OT_PYTHON -m pip install --user pipenv==2023.12.1
35-
- shell: bash
36-
run: $OT_PYTHON -m pip install --user virtualenv==20.30.0
37-
- shell: bash
38-
run: 'make -C ${{ inputs.project }} setup || make -C ${{ inputs.project }} setup'
40+
- name: Setup Python
41+
uses: actions/setup-python@v5
42+
with:
43+
python-version: ${{ inputs.python-version != 'false' && inputs.python-version || '3.10' }}
44+
- name: Check project type
45+
id: project-type
46+
shell: bash
47+
run: |
48+
# Only api and shared-data use UV for now
49+
if [ "${{ inputs.project }}" == "api" ] || [ "${{ inputs.project }}" == "shared-data" ]; then
50+
echo "type=uv" >> $GITHUB_OUTPUT
51+
elif [ -f "${{ inputs.project }}/Pipfile" ]; then
52+
echo "type=pipenv" >> $GITHUB_OUTPUT
53+
else
54+
echo "type=make" >> $GITHUB_OUTPUT
55+
fi
56+
- name: Install pipenv and virtualenv (original behavior - always installed)
57+
if: steps.project-type.outputs.type != 'uv'
58+
shell: bash
59+
run: |
60+
python -m pip install --upgrade pip
61+
python -m pip install --user pipenv==2023.12.1
62+
python -m pip install --user virtualenv==20.30.0
63+
- name: Install UV
64+
if: steps.project-type.outputs.type == 'uv'
65+
uses: ./.github/actions/python/install-uv
66+
- name: Cache UV packages
67+
if: steps.project-type.outputs.type == 'uv'
68+
uses: ./.github/actions/python/cache-uv
69+
with:
70+
lockfile-path: ${{ inputs.project }}/uv.lock
71+
- name: Setup Python Environment
72+
id: setup-env
73+
shell: bash
74+
run: |
75+
START_TIME=$(date +%s)
76+
echo "start-time=$START_TIME" >> $GITHUB_OUTPUT
77+
# Use the project type determined earlier
78+
PROJECT_TYPE="${{ steps.project-type.outputs.type }}"
79+
if [ "$PROJECT_TYPE" == "uv" ]; then
80+
echo "::notice::Using UV for dependency management"
81+
# Add dev extra if requested
82+
DEV_EXTRA=""
83+
if [ "${{ inputs.install-dev-deps }}" == "true" ]; then
84+
DEV_EXTRA="--extra dev"
85+
fi
86+
if [ -f "${{ inputs.project }}/uv.lock" ]; then
87+
# Use --frozen only if no extras are requested (extras may not be in lockfile)
88+
if [ -z "$DEV_EXTRA" ]; then
89+
cd ${{ inputs.project }} && uv sync --frozen
90+
else
91+
cd ${{ inputs.project }} && uv sync $DEV_EXTRA
92+
fi
93+
# Verify dev dependencies are installed if dev extra was used
94+
if [ -n "$DEV_EXTRA" ]; then
95+
echo "::notice::Verifying dev dependencies are installed..."
96+
uv pip list | grep -E "(sphinx|mypy|pytest|black)" || echo "::warning::Some dev dependencies may not be installed"
97+
fi
98+
else
99+
cd ${{ inputs.project }} && uv sync $DEV_EXTRA
100+
# Verify dev dependencies are installed if dev extra was used
101+
if [ -n "$DEV_EXTRA" ]; then
102+
echo "::notice::Verifying dev dependencies are installed..."
103+
uv pip list | grep -E "(sphinx|mypy|pytest|black)" || echo "::warning::Some dev dependencies may not be installed"
104+
fi
105+
fi
106+
else
107+
# For pipenv or make projects, just call make setup
108+
make -C ${{ inputs.project }} setup
109+
fi
110+
END_TIME=$(date +%s)
111+
DURATION=$((END_TIME - START_TIME))
112+
echo "duration=$DURATION" >> $GITHUB_OUTPUT
113+
echo "::notice::Setup completed in ${DURATION} seconds"

.github/workflows/api-test-lint-deploy.yaml

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ jobs:
108108
with:
109109
project: 'api'
110110
python-version: ${{ matrix.python }}
111+
install-dev-deps: 'true'
111112
- if: ${{ matrix.with-ot-hardware == 'false' }}
112113
name: Remove OT-3 hardware package
113114
run: make -C api setup-ot2
@@ -120,7 +121,11 @@ jobs:
120121
name: Test with opentrons_hardware
121122
run: make -C api test-cov
122123
- name: Ensure assets build
123-
run: make -C api sdist wheel
124+
run: |
125+
# Ensure uv is in PATH (should already be there from setup action via $GITHUB_PATH)
126+
# On Windows, $HOME maps to the user profile, so this works cross-platform
127+
export PATH="$HOME/.cargo/bin:$PATH"
128+
make -C api sdist wheel
124129
- name: Upload coverage report
125130
uses: 'codecov/codecov-action@v3'
126131
with:
@@ -141,9 +146,15 @@ jobs:
141146
run: |
142147
git fetch -f origin ${{ github.ref }}:${{ github.ref }}
143148
git checkout ${{ github.ref }}
149+
- name: Install UV
150+
uses: ./.github/actions/python/install-uv
144151
- uses: 'actions/setup-python@v4'
145152
with:
146153
python-version: '3.10'
154+
- name: Cache UV packages
155+
uses: ./.github/actions/python/cache-uv
156+
with:
157+
lockfile-path: package-testing/uv.lock
147158
- name: Set up package-testing
148159
id: setup
149160
if: ${{ matrix.os != 'windows-2022' }}
@@ -214,10 +225,7 @@ jobs:
214225
- uses: './.github/actions/python/setup'
215226
with:
216227
project: 'api'
217-
- name: 'build api distributables'
218-
shell: bash
219-
run: make -C api sdist wheel
220-
228+
install-dev-deps: 'false'
221229
# creds and repository configuration for deploying python wheels
222230
- if: ${{ !env.OT_TAG }}
223231
name: 'upload to test pypi'

.github/workflows/shared-data-test-lint-deploy.yaml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,24 @@ jobs:
9494
with:
9595
project: 'shared-data'
9696
python-version: ${{ matrix.python }}
97+
install-dev-deps: 'true'
9798
- name: 'set complex environment variables'
9899
uses: actions/github-script@v6
99100
with:
100101
script: |
101102
const { buildComplexEnvVars, } = require(`${process.env.GITHUB_WORKSPACE}/.github/workflows/utils.js`)
102103
buildComplexEnvVars(core, context)
103104
- name: Test
104-
run: make -C shared-data test-py
105+
run: |
106+
# Ensure uv is in PATH (should already be there from setup action via $GITHUB_PATH)
107+
# On Windows, $HOME maps to the user profile, so this works cross-platform
108+
export PATH="$HOME/.cargo/bin:$PATH"
109+
make -C shared-data test-py
105110
- name: Ensure assets build
106-
run: make -C shared-data dist-py
111+
run: |
112+
# Ensure uv is in PATH (should already be there from setup action via $GITHUB_PATH)
113+
export PATH="$HOME/.cargo/bin:$PATH"
114+
make -C shared-data dist-py
107115
- name: 'Upload coverage report'
108116
uses: codecov/codecov-action@v3
109117
with:
@@ -178,6 +186,7 @@ jobs:
178186
- uses: './.github/actions/python/setup'
179187
with:
180188
project: 'shared-data'
189+
install-dev-deps: 'false'
181190
- name: 'set complex environment variables'
182191
uses: actions/github-script@v6
183192
with:

api/Makefile

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
# opentrons api makefile
22

33
include ../scripts/push.mk
4-
include ../scripts/python.mk
4+
include ../scripts/python-uv.mk
55

66
SHX := npx shx
77

88
# make push wheel file (= rather than := to expand at every use)
99
firmware = $(wildcard smoothie/*.hex)
1010

11-
# python and pipenv config
12-
sphinx_build := $(pipenv) run sphinx-build -W --keep-going
11+
# python and sphinx config
12+
sphinx_build := $(python) -m sphinx -W --keep-going
1313
# todo(mm, 2021-10-04):
1414
# 1. Resolve all Sphinx warnings.
1515
# 2. Convert all recipes to use $(sphinx_build).
1616
# 3. Delete $(sphinx_build_allow_warnings).
1717
# github.com/Opentrons/opentrons/issues/6135
18-
sphinx_build_allow_warnings := $(pipenv) run sphinx-build
18+
sphinx_build_allow_warnings := $(python) -m sphinx
1919

2020
# Find the version of the wheel from git using a helper script. We
2121
# use python here so we can use the same version normalization that will be
@@ -66,14 +66,36 @@ all: clean wheel
6666

6767
.PHONY: setup
6868
setup:
69-
$(pipenv) sync $(pipenv_opts)
70-
$(pipenv) run pip freeze
69+
@UNAME_S=$$(uname -s 2>/dev/null || echo ""); \
70+
LINUX_EXTRA=""; \
71+
if echo "$$UNAME_S" | grep -qi linux; then \
72+
if [ -f pyproject.toml ] && grep -q '\[project.optional-dependencies\]' pyproject.toml 2>/dev/null && grep -A 10 '\[project.optional-dependencies\]' pyproject.toml 2>/dev/null | grep -q 'linux'; then \
73+
LINUX_EXTRA="--extra linux"; \
74+
fi; \
75+
fi; \
76+
if [ -f uv.lock ]; then \
77+
uv sync --frozen --extra dev $$LINUX_EXTRA; \
78+
else \
79+
uv sync --extra dev $$LINUX_EXTRA; \
80+
fi; \
81+
uv pip list
7182

7283
.PHONY: setup-ot2
7384
setup-ot2:
74-
$(pipenv) sync $(pipenv_opts)
75-
$(pipenv) run pip uninstall -y python-can
76-
$(pipenv) run pip freeze
85+
@UNAME_S=$$(uname -s 2>/dev/null || echo ""); \
86+
LINUX_EXTRA=""; \
87+
if echo "$$UNAME_S" | grep -qi linux; then \
88+
if [ -f pyproject.toml ] && grep -q '\[project.optional-dependencies\]' pyproject.toml 2>/dev/null && grep -A 10 '\[project.optional-dependencies\]' pyproject.toml 2>/dev/null | grep -q 'linux'; then \
89+
LINUX_EXTRA="--extra linux"; \
90+
fi; \
91+
fi; \
92+
if [ -f uv.lock ]; then \
93+
uv sync --frozen --extra dev $$LINUX_EXTRA; \
94+
else \
95+
uv sync --extra dev $$LINUX_EXTRA; \
96+
fi; \
97+
uv pip uninstall python-can -y; \
98+
uv pip list
7799

78100
.PHONY: clean
79101
clean: docs-clean
@@ -82,7 +104,7 @@ clean: docs-clean
82104

83105
.PHONY: teardown
84106
teardown:
85-
-$(pipenv) --rm
107+
rm -rf .venv
86108

87109
.PHONY: wheel
88110
wheel: export OPENTRONS_PROJECT=$(PROJECT)
@@ -171,7 +193,7 @@ dev:
171193

172194
.PHONY: local-shell
173195
local-shell:
174-
$(pipenv) shell
196+
uv run bash
175197

176198
.PHONY: push-no-restart
177199
push-no-restart: wheel

api/mypy.ini

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,29 @@ plugins = pydantic.mypy, decoy.mypy, numpy.typing.mypy_plugin
33
show_error_codes = True
44
warn_unused_configs = True
55
strict = True
6+
# Disable untyped decorator errors - hypothesis decorators don't have proper type stubs
7+
disallow_untyped_decorators = False
68

79
[pydantic-mypy]
810
init_forbid_extra = True
911
init_typed = True
1012
warn_required_dynamic_aliases = True
1113
warn_untyped_fields = True
1214

15+
# Ignore optional/local packages that may not be installed
16+
[mypy-opentrons_hardware.*]
17+
ignore_missing_imports = True
18+
19+
[mypy-performance_metrics.*]
20+
ignore_missing_imports = True
21+
22+
# Test-only dependencies that may not have type stubs
23+
[mypy-pytest_lazy_fixtures.*]
24+
ignore_missing_imports = True
25+
26+
[mypy-hypothesis]
27+
ignore_missing_imports = True
28+
29+
[mypy-hypothesis.*]
30+
ignore_missing_imports = True
31+

0 commit comments

Comments
 (0)