
uv 包构建与发布实战uv build、uv version 与 uv publish 完整工作流【免费下载链接】uvAn extremely fast Python package and project manager, written in Rust.项目地址: https://gitcode.com/GitHub_Trending/uv/uv本文围绕 uv 官方指南 Building and publishing a package 展开系统讲解如何使用uv build将 Python 项目构建为 sdist 与 wheel、如何用uv version以语义化方式更新版本号、以及如何使用uv publish将分发包发布到 PyPI 或自定义索引。文中所有实现细节均对照 uv 仓库源码核实读完即可在当前仓库或任意 uv 项目中完整复现“构建 → 改版本 → 发布 → 验证安装”的发布流水线。整体流程uv 把一个 Python 包从本地代码变成可发布制品的过程拆成了四个命令每个命令职责单一准备确认pyproject.toml中声明了[build-system]构建uv build在当前项目生成 sdist.tar.gz与 wheel.whl产物默认写入dist/改版本uv version在发布前以精确值或语义化 bump 更新pyproject.toml中的version发布uv publish将dist/中的分发包上传到包索引并可附带 PEP 740 构建证明attestations。准备项目在发布之前先确保项目具备可打包的构建系统配置。指南给出的关键行为是如果项目的pyproject.toml没有[build-system]定义uv sync等操作不会构建该项目但uv build会回退到传统 setuptools 构建系统继续工作用uv init创建的项目默认包含[build-system]定义因此开箱即可构建。官方强烈建议显式配置构建系统构建系统的完整说明见 项目配置文档。从源码结构看这一建议有明确的工程原因构建前端在发现工作区成员缺少[build-system]时会直接报错并在错误信息中直接给出可复制的模板构建前端[build-system] requires [uv_build0.x,1.0.0] # 实际运行时按当前 uv 主版本号生成区间 build-backend uv_build使用uv_build作为构建后端还有额外收益构建前端会优先走“直接构建”快速路径下文详述无需创建 PEP 517 隔离构建环境。构建包uv build最基本的构建命令$ uv build默认情况下uv build构建当前目录中的项目并把产物写入dist/子目录。更灵活的用法uv build SRC构建指定目录中的包SRC也可以是一个 sdist 归档文件此时构建出 wheeluv build --package PACKAGE构建当前工作区中指定的某个包。指南强调发布前推荐执行uv build --no-sources。因为uv build默认在解析build-system.requires中的构建依赖时遵循tool.uv.sources配置而使用pypa/build等其他构建工具时tool.uv.sources是失效的。用--no-sources预演能确保包在禁用 sources 的环境下依然能正确构建。完整参数对照 CLI 源码以下参数定义均取自 BuildArgs可作为日常使用的参数速查参数说明src位置参数构建来源目录或要转成 wheel 的 sdist 归档默认当前工作目录--package PACKAGE构建工作区中指定包工作区从src或当前目录发现与--all-packages互斥--all-packages别名--all构建工作区中所有可构建的包--out-dir/-o输出目录默认是源目录或工作区根目录下的dist/--sdist只构建源分发包--wheel只构建二进制分发包wheel--force-pep517强制走 PEP 517 构建不使用 uv 构建后端的快速路径--clear构建前清空输出目录删除过期产物--build-constraints/-c用requirements.txt风格的约束文件约束构建依赖版本只约束版本不会额外引入包--no-build-logs隐藏构建后端输出的日志输出目录的默认逻辑在 构建实现 中若属于工作区写入工作区根目录/dist否则写入源目录/dist若src是 sdist 文件则写入该文件所在目录。底层机制直接构建与 PEP 517 两条路径从 build_frontend.rs 的BuildAction判定逻辑可以看到uv 对每个待构建包会做一次check_direct_build检查若构建后端是uv_build且版本兼容走DirectBuild快速路径——直接调用内置构建后端跳过 PEP 517 虚拟环境的创建否则回退到Pep517路径创建隔离构建环境默认开启 build isolation在其中安装build-system.requires再执行钩子--force-pep517可以强制走 PEP 517用于验证包在其他构建工具下的兼容性。此外构建用的 Python 解释器按如下顺序发现源码① 命令行显式请求② 项目中的.python-version文件③pyproject.toml的Requires-Python。更新版本号uv versionuv version在发布前提供版本更新便利。查看当前版本的方式见 项目指南。精确设置版本直接把版本作为位置参数$ uv version 1.0.0 hello-world 0.7.0 1.0.0预览而不写入用--dry-run只打印将发生的变更不修改pyproject.toml$ uv version 2.0.0 --dry-run hello-world 1.0.0 2.0.0 $ uv version hello-world 1.0.0语义化递增用--bump按语义化版本分量递增$ uv version --bump minor hello-world 1.2.3 1.3.0--bump支持的分量来自 VersionBump 枚举major、minor、patch、stable、alpha、beta、rc、post、dev典型效果bump 分量示例major1.2.3 2.0.0minor1.2.3 1.3.0patch1.2.3 1.2.4stable1.2.3b4.post5.dev6 1.2.3移除预发布分量保留 local 分量alpha/beta/rc1.2.3b4 1.2.3b5post1.2.3.post5 1.2.3.post6dev1.2.3a4.dev6 1.2.3a4.dev7重复给出多个分量时按从大到小major到dev的顺序应用——源码注释明确说明实现会对操作排序后再依次执行VersionArgs 附近的注释使用者无需自己考虑顺序。显式指定分量数值--bump componentvalue$ uv version --bump patch --bump dev66463664 hello-world 0.0.1 0.0.2.dev66463664稳定版 → 预发布在预发布分量之外再 bump 一个 major/minor/patch$ uv version --bump patch --bump beta hello-world 1.3.0 1.3.1b1 $ uv version --bump major --bump alpha hello-world 1.3.0 2.0.0a1预发布 → 下一个预发布只需 bump 对应的预发布分量$ uv version --bump beta hello-world 1.3.0b1 1.3.0b2预发布 → 稳定版用stable清除预发布分量$ uv version --bump stable hello-world 1.3.1b2 1.3.1指南提示uv version修改项目后默认会执行 lock 和 sync。用--frozen可跳过 lock 与 sync用--no-sync只跳过 sync。这两个开关与uv sync、uv lock等命令共用同一套语义见 VersionArgs。uv version的实际修改逻辑位于 project_version它通过uv-pep440的BumpCommand计算新版本并通过PyProjectTomlMut写回pyproject.toml。发布包uv publish若需要从 GitHub Actions 发布到 PyPI完整的 CI 配置见 GitHub 集成指南。基本命令$ uv publish默认上传dist/目录CLI 中files参数默认为dist/*支持 glob且只选择 wheel、sdist 及它们的 attestations忽略其他文件PublishArgs。认证方式方式参数环境变量Token推荐--tokenUV_PUBLISH_TOKEN用户名--username/-uUV_PUBLISH_USERNAME密码--password/-pUV_PUBLISH_PASSWORDkeyring--keyring-providerUV_KEYRING_PROVIDER从 gather_credentials 的文档注释可以看到完整的凭据解析优先级URL 内嵌的用户名/密码、--token/--username/--passwordCLI 覆盖环境变量、keyring、trusted publishing token最后才是在终端交互提示输入。PyPI 注意PyPI 已不再支持用户名 密码发布必须使用 token。使用 token 等价于--username __token__并把 token 作为密码。这一点在源码中也得到印证trusted publishing 得到的 token 同样以__token__作为用户名提交publish.rs。Trusted publishing可信发布在 GitHub Actions 等受支持的 CI 环境中使用可信发布时无需任何凭据——只需在 PyPI 项目上添加 trusted publisher 即可。uv 的行为细节均有源码佐证使用可信发布时uv 在发布完成后会主动使 PyPI 签发的短时 token 失效burn即使发布失败也会尝试进一步压缩 token 的暴露窗口burn_trusted_publishing_token 调用若失效操作本身失败uv 只发出警告不改变发布结果通过--token或UV_PUBLISH_TOKEN显式提供的 token不会被吊销因为那是用户自己的长效凭据。自定义索引publish-url 与 --index使用[[tool.uv.index]]配置自定义索引时为其添加publish-url然后uv publish --index name即可。例如[[tool.uv.index]] name testpypi url https://test.pypi.org/simple/ publish-url https://test.pypi.org/legacy/ explicit true等价关系来自 CLI 帮助文本uv publish --index pypi等价于uv publish --publish-url https://upload.pypi.org/legacy/ --check-url https://pypi.org/simple——即索引的publish-url用于上传url自动作为查重用的 check URL。注意使用uv publish --index name时pyproject.toml必须存在也就是说发布用的 CI 任务里需要有 checkout 步骤。未指定--publish-url时默认上传到 PyPI 的https://upload.pypi.org/legacy/。另外离线模式下uv publish会直接报错拒绝执行源码。部分失败的恢复--check-urluv publish会对失败的上传进行重试但仍可能中途失败一部分文件已上传、一部分缺失。处理策略PyPI直接重试同一条命令即可完全相同的文件会被索引忽略其他注册表使用--check-url index url注意传的是索引 URL 而非发布 URL。使用--index时会自动以索引 URL 作为 check URL。check 机制的行为publish.rs 中的查重逻辑上传前先检查索引若完全相同的文件已存在则跳过并提示File ... already exists, skipping上传出错时会再次检查以处理“同一文件被并行上传两次”的竞争场景。已存在的文件必须与此前上传的逐字节一致这可以避免同版本下 sdist 与 wheel 内容不一致的错误发布。该索引需支持 SHA-256、SHA-384 或 SHA-512 之一用于比对。其他实用开关--dry-run只本地校验分发元数据并在提供--check-url/--index时检查索引中已存在的文件但不上传files位置参数支持 glob用于指定非默认目录的分发包。上传 attestations构建证明注意部分第三方索引可能不支持 attestations甚至会拒绝而非静默忽略带 attestations 的上传。遇到此类问题时用--no-attestations或环境变量UV_PUBLISH_NO_ATTESTATIONS关闭默认行为。另请注意uv publish目前不生成attestationsattestations 需要在发布前单独创建。uv publish支持向 PyPI 等支持 PEP 740 的注册表上传 attestations。uv 会自动发现并匹配attestations——给定如下的dist/目录uv publish会把每个 attestation 与其对应的分发包一起上传$ ls dist/ hello_world-1.0.0-py3-none-any.whl hello_world-1.0.0-py3-none-any.whl.publish.attestation hello_world-1.0.0.tar.gz hello_world-1.0.0.tar.gz.publish.attestation从源码看文件分组由group_files_for_publishing完成且上传顺序固定为wheel 在前、sdist 在后同类型内按文件名排序publish.rs。安装验证发布后用uv run验证包可安装、可导入$ uv run --with PACKAGE --no-project -- python -c import PACKAGE--no-project用于避免把本地项目目录中的包当作安装来源确保验证的是索引上的真实制品。提示如果包刚发布不久可能需要加--refresh-package PACKAGE避免命中本地缓存的旧版本。下一步构建与发布的更广泛背景可参考 PyPA 官方的 build-and-publish 指南uv 文档在“Next steps”中给出的延伸阅读方向与 CI/其他软件集成集成指南索引GitHub Actions 发布到 PyPI 的完整配置GitHub 指南。【免费下载链接】uvAn extremely fast Python package and project manager, written in Rust.项目地址: https://gitcode.com/GitHub_Trending/uv/uv创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考