以下是我对您的清单的看法。您可以实现一定范围的自动化,我将尝试提供一个合理的起点,然后提供一些提示,告诉您如何从那里走得更远。
无 CD 的 CI
采用这部分应该已经摆脱了大部分烦人的手动工作,并且您可以根据需要越来越多地自动化。如果你不习惯维护大量的 CI 代码,你应该从这里开始。
您需要的是一个 CI(正如您已经指出的)和一个包管理器。您无法解决的问题是使用 git 推送您的更改和一个新标签,因此第 5 步和第 6 步的部分内容仍然是手动的。
包管理
我将使用poetry 来保持简洁,因为我喜欢它[1],但也有other options。这将处理第 2、3、7、8 步和未列出的第 10 步,“更新我的依赖项并测试它们的兼容性”,一旦出现问题,就会非常烦人。
使用诗歌时的坏消息是您需要将所有打包配置移动到一个新文件pyproject.toml。好消息是,您不再需要单独的 setup.py、setup.cfg、MANIFEST.in 或 requirements.txt,因为 pyproject.toml 是包装和其他工具的临时标准,诗歌也有walkthrough 关于如何移植所有相关信息。
设置完成后,新的部署工作流程将是:
$ 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 的正确设置取决于您打算使用哪一个。 list for github 很长,所以我将重点介绍 gitlab 的内置 CI。它是免费的,几乎没有什么魔力(这使得它具有相当的便携性),并且 CI 运行器的二进制文件是 open, free, and actually documented,因此您可以在本地调试您的 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 和test 阶段可以一口气处理步骤1 和9,同时还针对已安装的包而不是源文件运行测试套件。虽然只有在项目中有 src-layout 时它才能正常工作,这使得本地源无法从项目根目录导入。关于为什么这是一个好主意的一些信息here 和 here。
Poetry 可以创建一个 src-layout 模板,您可以使用 poetry new my_django_lib --src 将代码移动到其中。
更新日志
虽然有来自提交消息的automatically create a changelog 的工具,但keeping a good changelog 是那些从手工处理中受益匪浅的东西之一。所以,我的建议是第 4 步不要自动化。
一种思考方式是手动 CHANGELOG 文件包含与您的用户相关的信息,并且应该只包含新功能、重要错误修复和弃用等信息。
可能对贡献者或插件作者很重要的更细粒度的信息将位于 MR、提交消息或问题讨论中,不应将其放入 CHANGELOG。您可以尝试以某种方式收集它,但导航这样的AUTOLOG 可能与筛选我刚才提到的主要来源一样麻烦。
所以简而言之,第 5 步和第 6 步的变更日志相关部分可以跳过。
带有 CD 的 CI
添加CD并没有太大变化,只是不再需要手动释放。如果 CI 出现故障、出现错误或您不想等待管道发布修补程序,您仍然可以随诗发布。
这将通过以下方式改变工作流程:
- 日常工作
- 写代码(还不能避免)
- 在提交消息和/或 MR 中记录进度(我更喜欢 MR,即使是我自己的更改,并在合并时压缩所有提交)
- 推送到 gitlab / 合并 MRs
- 发布时
- 创建一个标签,运行
poetry version 或者poetry update
- 在
CHANGELOG 中写入发行说明
- 推送到 gitlab
如果您使用 supply the secrets PYPI_USER 和 PYPI_PASSWORD,对之前的 .gitlab-ci.yml 文件的此添加应该会立即生效:
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/*
一些有用的链接:
[1] 除此之外,诗歌还 1)为您处理 virtualenv,2)创建一个散列锁文件以防您需要可重现的构建,以及 3)使贡献更容易,因为您只有克隆存储库后运行“诗歌安装”并准备就绪。