python - 自动化 Python 包发布过程
问题描述
我刚刚开始了一个开源 Python 项目,我希望它有一天会流行起来。目前要发布一个新版本,我必须做一些事情。
- 测试所有的东西。
- 编辑
mypackage.VERSION
变量,setup.py
从__init__
- 构建包和轮子
python setup.py sdist bdist_wheel
- 将更改日志条目写入
CHANGELOG
文件 - 提交我的更改,回显其中的一些更改日志
- 将该提交标记为发布,再次复制该更改日志条目。
- 拖入我构建的文件,以便人们可以从版本中下载它们
- 使用 Twine 将包推送到 PyPI
- 通过 PyPI 在我的登台服务器上再次测试。
如果我必须用九个要点来总结我讨厌我的项目的所有内容,我想我们会看到一个非常相似的列表。最重要的是,在我编写新版本号并编写提交/更改日志消息之前,这非常无聊。
我能否以某种方式自动化这些任务,例如,让 GitHub CI仅从我的提交中完成所有事情?
我已经有十年的 Python 经验和一点 CI,但我对打包 Python 和积极与 PyPI 交互还是很陌生。我怀疑我不是唯一一个被这里的手动重复逼疯的人,我只是在寻找可以使这个过程更容易的工具(或服务)。
解决方案
以下是我对您的清单的看法。您可以实现一定范围的自动化,我将尝试提供一个合理的起点,然后提供一些提示,告诉您如何从那里走得更远。
无 CD 的 CI
采用这部分应该已经摆脱了大部分烦人的手动工作,并且您可以根据需要越来越多地自动化。如果你不习惯维护大量的 CI 代码,你应该从这里开始。
您需要的是一个 CI(正如您已经指出的)和一个包管理器。您无法解决的问题是使用 git 推送您的更改和一个新标签,因此第 5 步和第 6 步的部分内容仍然是手动的。
包管理
我将使用诗歌来保持简洁,因为我喜欢它[1],但也有其他选择。这将处理第 2、3、7、8 步和未列出的第 10 步,“更新我的依赖项并测试它们的兼容性”,一旦出现问题,这将非常烦人。
使用诗歌时的坏消息是您需要将所有打包配置移动到一个新文件中,pyproject.toml
. 好消息是,您不再需要单独setup.py
的 , setup.cfg
,MANIFEST.in
或requirements.txt
任何其他工具,因为pyproject.toml
它是包装和其他工具的临时标准,并且诗歌还提供了有关如何移植所有相关信息的演练。
设置完成后,新的部署工作流程将是:
$ poetry update # update dependencies, may be skipped
$ poetry version # bump version
Bumping version from 1.1.2 to 1.1.3
# finalize git stuff, e.g. add -u, commit -m 'v1.1.3', tag v1.1.3, push
$ poetry publish --build # build and publish to PyPI
Building my_django_lib (1.1.3)
- Building sdist
- Built my_django_lib-1.1.3.tar.gz
- Building wheel
- Built my_django_lib-1.1.3-py3-none-any.whl
Publishing my_django_lib (1.1.3) to PyPI
- Uploading my_django_lib-1.1.3-py3-none-any.whl 100%
- Uploading my_django_lib-1.1.3.tar.gz 100%
这应该已经比您当前正在做的要短得多。如果你总是执行完全相同的 git 命令,不害怕自动推送,并妥善保管你的.gitignore
文件,请随意添加类似此函数的~/.bashrc
内容并调用它:
git_cord () {
version=$(grep pyproject.toml -e '(?<=^version = ")(.*)(?=")' -Po)
git add -u
git commit -m "${version}"
git tag "${version}"
git push -u origin "${version}"
}
开始使用 gitlab-CI
CI 原则上可以处理与部署过程相关的所有事情,包括版本更新和发布。但是第一个要求您的 CI 可以推送到您的 repo(这有烦人的副作用),而后者可以发布到您的 PyPI(这是有风险的,并且使调试 CI 变得很痛苦)。我认为更喜欢手动完成这两个步骤并不罕见,因此这种最小的方法将只处理第 1 步和第 9 步。之后可以包括更广泛的测试和构建作业。
CI 的正确设置取决于您打算使用哪一个。github的列表很长,所以我将重点介绍 gitlab 的内置 CI。它是免费的,几乎没有什么魔力(这使得它具有相当的便携性),并且 CI 运行器的二进制文件是开放的、免费的,并且实际记录在案,因此您可以在本地调试您的 CI,或者如果免费的运行器不启动并连接新的运行器'不给你剪。
这是一个小.gitlab-ci.yml
程序,您可以将其放入项目根目录以运行测试。管道中的每个作业(跳过设置和安装命令)也应该在您的开发环境中可执行,保持这种状态可以为维护者提供更好的体验。
image: python:3.7-alpine
stages:
- build
- test
packaging:
stage: build
script:
- pip install poetry
- poetry build
artifacts:
paths:
- dist
pytest:
stage: test
script:
- pip install dist/*.whl
- pip install pytest
- pytest
像这样设置build
andtest
阶段可以一口气处理步骤 1 和 9,同时还针对已安装的包而不是源文件运行测试套件。虽然只有在项目中有 src-layout 时它才能正常工作,这使得本地源无法从项目根目录导入。关于为什么这将是一个好主意的一些信息在这里和这里。
Poetry 可以创建一个 src-layout 模板,您可以使用poetry new my_django_lib --src
.
变更日志
虽然有一些工具可以根据提交消息自动创建变更日志,但保持良好的变更日志是从手工处理中受益匪浅的事情之一。所以,我的建议是第 4 步不要自动化。
一种思考方式是手册CHANGELOG
文件包含与您的用户相关的信息,并且应该只包含新功能、重要错误修复和弃用等信息。
对贡献者或插件作者可能很重要的更细粒度的信息将位于 MR、提交消息或问题讨论中,不应将其放入CHANGELOG
. 您可以尝试以某种方式收集它,但导航这样的AUTOLOG
可能与筛选我刚才提到的主要来源一样麻烦。
所以简而言之,可以跳过第 5 步和第 6 步的变更日志相关部分。
带有 CD 的 CI
添加CD并没有太大的变化,只是不再需要手动释放。如果 CI 出现故障、出现错误,或者您不想等待管道发布修补程序,您仍然可以使用诗歌进行发布。
这将通过以下方式改变工作流程:
- 日常工作
- 编写代码(还不能避免这个)
- 记录提交消息和/或 MR 的进度(我更喜欢 MR,即使是我自己的更改,并在合并时压缩所有提交)
- 推送到 gitlab / 合并 MR
- 发布时
- 创建一个标签,运行
poetry version
,也许poetry update
- 写发行说明
CHANGELOG
- 推送到 gitlab
- 创建一个标签,运行
.gitlab-ci.yml
如果您提供秘密 PYPI_USER
和PYPI_PASSWORD
:
stages:
- build
- test
- release
[...] # packaging and pytest unchanged
upload:
stage: release
only:
- tags
# Or alternatively "- /^v\d+\.\d+\.\d+/" if you also use non-release
# tags, the regex only matches tags that look like this: "v1.12.0"
script:
- pip install poetry
- poetry publish -u ${PYPI_USER} -p ${PYPI_PASSWORD} dist/*
一些有用的链接:
.gitlab-ci.yml
文件- 预定义变量列表,这是大多数 gitlab CI 的晦涩之处
- 我的模板的长版本
.gitlab-ci.yml
,带有可能对您有用或可能没有用的附加阶段。它需要您的代码的 src 布局。
[1]除此之外,poetry 还 1) 为您处理 virtualenv,2) 创建一个散列锁文件以防您需要可重复的构建,以及 3) 使贡献更容易,因为您只需在克隆后运行“poetry install”回购并准备就绪。
推荐阅读
- c# - 获取商品价格更改的最后日期
- unit-testing - 如何模拟同一类的方法?
- scala - 当多个文件合并在一起时,如何将文件名添加到数据框中的列?
- angular - Angular CDK 的 Drag&Drop,保持顺序直到 drop
- swift - 如何删除 PDF 文档边距
- c# - 如何在 Native C++ 中将 PFX 文件读入 X509 并将此证书传递给 c# 应用程序
- tfs - 将我的免费试用版 Azure Devops 升级到 LIcensed
- spring-boot - 微服务异步响应
- javascript - 如何创建一个反应原生的全屏模式,它将覆盖带有选项卡的 SafeAreaView?
- redirect - htaccess 将所有变体重定向到 https