以下都是我实践过的步骤,内容包含
- 如何使用 poetry 创建项目
- 从 git 的 tag 中获取版本号
- 配置 Github Actions
- 配置单元测试上传到 codecov.io
- 配置 tag push 自动触发 publish
- 更新 README 中的 badge
 
Poetry
poetry 可以代替目前的 setup.py 和 requirements.txt 组合,虽然部分命令跑起来有点慢,但是胜在方便
下面这个文件是可以通过命令poetry init命令生成的,不用复制粘贴。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 
 | [tool.poetry]name = "sshg"
 version = "0.1.0"
 description = "ssh from config with arrow select support"
 authors = ["codeskyblue <[email protected]>"]
 license = "MIT"
 readme = "README.md"
 
 [tool.poetry.dependencies]
 python = "^3.8"
 Jinja2 = "^3.1.2"
 requests = "*"
 dataclasses-json = "*"
 pyyaml = "*"
 prompt_toolkit = "*"
 pexpect = "*"
 
 [tool.poetry.dev-dependencies]
 pytest = "^7.2.0"
 pytest-cov = "^2"
 
 
 [tool.poetry.scripts]
 sshg = "sshg:main"
 
 
 [tool.poetry-dynamic-versioning]
 enable = true
 
 [build-system]
 requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"]
 build-backend = "poetry_dynamic_versioning.backend"
 
 | 
如果是通过交互式命令创建出来的 pyproject.toml 需要再添加点内容,其中 build-system 部分需要替换掉
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | [tool.poetry.scripts]
 sshg = "sshg:main"
 
 
 [tool.poetry-dynamic-versioning]
 enable = true
 
 
 [build-system]
 requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"]
 build-backend = "poetry_dynamic_versioning.backend"
 
 | 
下面是一些常用命令
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | poetry update
 
 
 poetry install
 
 
 poetry shell
 
 
 poetry build
 
 | 
参考
Github Actions
创建配置文件
参考配置文件,根据需要修改,下面的文件直接复制到路径.github/workflows/python-app.yml
下面的命令可以方便的完成
| 12
 
 | mkdir -p .github/workflowscat > .github/workflows/python-app.yml
 
 | 
下面的内容是要贴过去的内容
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 
 | name: Python Package
 on:
 push:
 branches: [master]
 tags:
 - v*
 pull_request:
 branches: [master]
 
 jobs:
 test:
 runs-on: ubuntu-latest
 steps:
 - uses: actions/checkout@v2
 
 - name: Set up Python 3.9
 uses: actions/setup-python@v2
 with:
 python-version: 3.9
 
 - name: Install dependencies
 run: |
 python -m pip install --upgrade pip
 pip install poetry
 poetry install
 
 - name: Run tests with coverage
 run: |
 poetry run pytest --cov=. --cov-report xml --cov-report term
 
 - name: Upload coverage to Codecov
 uses: codecov/codecov-action@v3
 
 publish:
 runs-on: ubuntu-latest
 needs: test
 if: startsWith(github.ref, 'refs/tags/')
 steps:
 - uses: actions/checkout@v3
 
 - name: Set up Python
 uses: actions/setup-python@v4
 with:
 python-version: 3.9
 
 - name: Install dependencies
 run: |
 python -m pip install --upgrade pip
 pip install poetry
 
 - name: Build
 run: |
 poetry self add "poetry-dynamic-versioning[plugin]"
 rm -fr dist/ && poetry build
 
 - name: Publish distribution 📦 to PyPI
 uses: pypa/gh-action-pypi-publish@release/v1
 with:
 password: ${{ secrets.PYPI_TOKEN }}
 
 | 
正常的话可以看到 github 的 actions 被正常触发

配置文件可以本地先测试一下,使用这个项目 https://github.com/nektos/act
运行命令 act --list就可以检查语法是否正常了。
配置 PYPI_TOKEN
先要拿到 token
https://pypi.org/manage/account/token/
然后生成的 token 添加到项目的 Repository secrets 中去,下面用图来说明一下

Name 就写PYPI_TOKEN,Secret 就把刚才生成的 token 帖进去

Coverage
https://codecov.io/ 也需要设置一下变量 CODECOV_TOKEN,进入到指定项目中会有指引,这里就不写了。另外 badge 也可以从网站上直接 Copy 下来。
pyproject.toml 中新增下面的内容
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 
 | [tool.coverage.run]branch = true
 
 [tool.coverage.report]
 
 exclude_also = [
 
 "def __repr__",
 "if self\\.debug",
 
 
 "raise AssertionError",
 "raise NotImplementedError",
 
 
 "if 0:",
 "if __name__ == .__main__.:",
 
 
 "@(abc\\.)?abstractmethod",
 ]
 
 ignore_errors = true
 omit = [
 "tests/*",
 "docs/*"
 ]
 
 | 
文件文件 coveragerc
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | [run]branch = true
 
 [report]
 
 exclude_also =
 
 "def __repr__",
 "if self\\.debug",
 
 
 "raise AssertionError",
 "raise NotImplementedError",
 
 
 "if 0:",
 "if __name__ == .__main__.:",
 
 # Don't complain about abstract methods, they aren't run:
 "@(abc\\.)?abstractmethod",
 
 ignore_errors = true
 omit =
 "tests/*",
 "docs/*"
 
 | 
有时候需要忽略部分含,可以通过注释来实现
| 12
 3
 4
 5
 
 | a = my_function1()if debug:
 msg = "blah blah"
 log_message(msg, a)
 b = my_function2()
 
 | 
参考:https://coverage.readthedocs.io/en/latest/config.html
Badge
这是个好东西,可以直接展示覆盖率,最新版本号之类的东东
比如

https://badge.fury.io/for/py
通过这个网站就可以快速生成你需要的 badge,使用体验很好
参考