关于 migrate-to-uv
此技能指导开发者将 Keboola 组件从 pip 和 requirements.txt 迁移到 uv 与 pyproject.toml,适用于基于 Docker 的组件维护。内容涵盖依赖、Ruff、Docker、CI 和模板对齐步骤。
主要功能
- 01将依赖迁移至 uv 和 pyproject.toml
- 02配置 Ruff 检查与格式化
- 03更新多阶段 Docker 构建
- 04替换 GitHub Actions 工作流
- 05检查与组件模板的对齐情况
适用场景
- 01现代化 Keboola 组件的 Python 打包方式
- 02在组件构建中加入检查与测试阶段
- 03随依赖更新部署工作流
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ keboola/ ai-kit --skill migrate-to-uv安装后在 Claude Code 中输入/migrate-to-uv确认已加载。
附带文件references/examples.mdreferences/troubleshooting.md
详细介绍
迁移到 uv 构建系统
将一个 Keboola 组件(基于 Docker,通过 ECR 部署)从 requirements.txt + pip 迁移到 pyproject.toml + uv,并使用 ruff 进行代码检查。
请使用你可用的工具自行执行所有步骤。不要委派给或调用任何其他 Agent(component-builder、develop-component 或类似 Agent)——第 6 阶段的 component-developer:component-defaults 除外。
必须完成以下所有步骤。不要跳过任何步骤——如果文件不存在,请直接继续,不要提示。
步骤 0:读取当前状态
cat requirements.txt
grep "FROM python:" Dockerfile
cat .github/workflows/push.yml
提交 1:migrate to pyproject.toml 📦
创建 pyproject.toml
创建一个包含元数据和 ruff 配置的最简 pyproject.toml,但暂不添加依赖项——接下来会用 uv add 添加:
- 始终使用
requires-python = "~=3.13.0"和target-version = "py313" - 暂时将
dependencies = []留空
然后使用 uv 从 requirements.txt 填充依赖项:
# Add all main deps at once
uv add -r requirements.txt
# Move test-only deps to the dev group (common ones: pytest, mock, freezegun, responses)
# For each test dep found in requirements.txt:
uv remove <test-dep>
uv add --group dev <test-dep>
uv add 会自动将固定版本转换为 >= 范围,并就地更新 uv.lock——无需手动转换。
删除文件
rm -f requirements.txt
rm -f .flake8 flake8.cfg
rm -f scripts/build_n_run.ps1 scripts/run.bat scripts/run_kbc_tests.ps1
rm -f scripts/update_dev_portal_properties.sh
rm -rf docs/imgs/
rm -f component_config/configuration_description.md component_config/stack_parameters.json
(如果文件不存在,rm -f 会静默执行,不会报错或中断。)
填充 component_config/ URL(如果这些文件当前为空)
component_config/documentationUrl.md → https://github.com/keboola/REPO/blob/master/README.md
component_config/licenseUrl.md → https://github.com/keboola/REPO/blob/master/LICENSE.md
component_config/sourceCodeUrl.md → https://github.com/keboola/REPO
更新 .gitignore
如果尚未包含以下行,则添加:
*.egg-info/
.venv/
.DS_Store
/data
将裸写的 data/ 替换为 /data。移除重复的 .vscode/ 条目。
提交
git add -u # stages all deletions
git add pyproject.toml uv.lock .gitignore component_config/
git commit -m "migrate to pyproject.toml 📦"
提交 2:uv 💜
更新 Dockerfile
使用多阶段构建模式。 base 阶段由 test 和 production 共用,这样可保持生产镜像精简(不含开发依赖和测试文件)。
FROM python:3.13-slim AS base
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
# apt-get installs MUST come before uv sync
# RUN apt-get update && apt-get install -y <packages> ← keep if already present
WORKDIR /code/
COPY pyproject.toml uv.lock ./
ENV UV_PROJECT_ENVIRONMENT="/usr/local/"
RUN uv sync --no-dev --frozen
COPY src/ src/
COPY scripts/ scripts/
COPY deploy.sh .
FROM base AS test
RUN uv sync --all-groups --frozen
COPY tests/ tests/
RUN uv run ruff check src/ tests/
CMD ["uv", "run", "pytest", "tests/", "-v"]
FROM base AS production
CMD ["python", "-u", "/code/src/component.py"]
说明:
base只安装生产依赖(--no-dev);test在此基础上添加开发依赖- Ruff 检查在
test阶段的镜像构建时运行——尽早发现失败 - 使用
ENV KEY="value"语法(不要使用旧式ENV KEY value) - 任何位置都不得使用
pip install - 所有
apt-get代码块都必须放在RUN uv sync之前
更新 scripts/build_n_test.sh
#!/bin/sh
set -e
ruff check
python -m pytest tests/ --tb=short -q
更新 tests/__init__.py
替换旧的 os.path 写法:
import sys
from pathlib import Path
sys.path.append(str(Path(__file__).resolve().parent.parent / "src"))
更新 .github/workflows/push.yml
标准的 push.yml 使用与多阶段 Dockerfile 匹配的多作业流水线。不要逐个修补步骤,而应将整个文件替换为标准模板(来自第 6 阶段 / component-defaults),并且只更新此组件的 env: 代码块:
env:
KBC_DEVELOPERPORTAL_APP: "vendor.component-id" # full component ID from Developer Portal
KBC_DEVELOPERPORTAL_VENDOR: "vendor" # your vendor name
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
KBC_DEVELOPERPORTAL_USERNAME: ${{ vars.KBC_DEVELOPERPORTAL_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
KBC_DEVELOPERPORTAL_PASSWORD: ${{ secrets.KBC_DEVELOPERPORTAL_PASSWORD }}
KBC_TEST_PROJECT_CONFIGS: ""
KBC_STORAGE_TOKEN: ${{ secrets.KBC_STORAGE_TOKEN }}
新流水线结构(保持标准模板中的原样):
push_event_info— 检测分支/标签,输出is_deploy_ready(要求为默认分支 + 语义化标签)build-test— 构建--target test阶段,并上传为*-test.tar工件tests— 下载测试工件并运行容器(默认 CMD = pytest;ruff 已在构建时运行)tests-kbc— 如果已设置KBC_TEST_PROJECT_CONFIGS和令牌,则运行 KBC 集成测试build-production— 在所有测试通过后构建--target production阶段,并上传为*.tar工件push— 加载生产工件并推送到 ECRdeploy— 仅当is_deploy_ready == true时,在 Developer Portal 中设置标签update_developer_portal_properties— 运行scripts/developer_portal/update_properties.sh
生成 / 验证锁文件
uv add 已在提交 1 期间更新了 uv.lock。运行以下命令,确保文件完全一致:
uv sync --all-groups
提交
git add Dockerfile scripts/ tests/ .github/workflows/
git commit -m "uv 💜"
提交 3:ruff linting baseline 🎨
ruff format .
ruff check --fix .
如果有文件更改,则提交:
git add src/ tests/
git commit -m "ruff linting baseline 🎨"
阶段 6:Cookiecutter 对齐检查
使用 Task 工具加载规范模板文件:
- subagent_type:
component-developer:component-defaults - prompt:
"Return the canonical Keboola component template files."
然后将以下各项与返回的规范版本进行比较:
| 组件文件 | 规范版本 |
|---|---|
Dockerfile | 来自 component-defaults |
.github/workflows/push.yml | 来自 component-defaults |
scripts/build_n_test.sh | 来自 component-defaults |
docker-compose.yml | 来自 component-defaults |
.pre-commit-config.yaml | 来自 component-defaults |
修复结构差异。保留组件专属的添加项(自定义 apt 包、SSL 证书等)。
根据规范版本创建缺失文件(旧组件通常缺少 .pre-commit-config.yaml)。
git add Dockerfile scripts/ .github/workflows/ docker-compose.yml .pre-commit-config.yaml
git commit -m "align with cookiecutter template 🍪"
验证
# Build and run tests (ruff runs at build time inside the test stage)
docker build --target test -t test-component .
docker run test-component
# Optionally verify the production image builds cleanly
docker build --target production -t prod-component .
常见模式
依赖项转换:
requirements.txt pyproject.toml
keboola.component==1.4.4 "keboola-component>=1.4.4"
mock "mock>=5.2.0" (in dev group)
Ruff 配置(pyupgrade 始终使用 "UP"):
[tool.ruff]
line-length = 120
target-version = "py313"
[tool.ruff.lint]
extend-select = ["I", "UP"]