⚙️ GitHub Actions的CLI助手 + 可重用的工作流
项目描述
gha-utils
CLI + 可复用工作流程
多亏了这个项目,我能够 每天只需点击两次即可发布多个 Python 软件包。
此存储库包含一组可复用的工作流程和其配套的 CLI(即 gha-utils
,代表 GitHub Action 工作流程工具)。
它专为基于 uv
的 Python 项目设计(以及作为奖励的 Awesome List 项目)。
它负责
- 版本升级
- 自动修复格式:Python、Markdown、JSON、拼写错误
- 代码检查:Python 类型使用
mypy
、YAML、zsh
、GitHub Actions、链接、Awesome 列表、密钥 - 为 Linux / macOS / Windows 上的
x86_64
&arm64
编译 Python 二进制文件 - 构建 Python 软件包并将其上传到 PyPi
- Git 版本标记和 GitHub 发布创建
- 同步:
uv.lock
、.gitignore
、.mailmap
和 Mermaid 依赖关系图 - 自动锁定已关闭的未活跃问题
- 静态图像优化
- 构建 Sphinx 文档并部署,以及
autodoc
更新 - 标签管理,具有基于文件和内容的规则
不会在背后进行任何操作。每当提出更改时,都会创建一个 PR,因此您可以进行审查,类似于 dependabot。
gha-utils
CLI
可执行文件
gha-utils
最新版本的独立可执行文件作为直接下载在几个平台和架构上提供
平台 | x86_64 |
arm64 |
---|---|---|
Linux | 下载 gha-utils-linux-x64.bin |
|
macOS | 下载 gha-utils-macos-x64.bin |
下载 gha-utils-macos-arm64.bin |
Windows | 下载 gha-utils-windows-x64.exe |
运行开发版本
$ git clone https://github.com/kdeldycke/workflows
$ cd workflows
$ python -m pip install uv
$ uv venv
$ source .venv/bin/activate
$ uv pip install .
$ uv run -- gha-utils
可复用工作流程集合
此存储库包含自动化大部分无聊任务的工作流程。
这些工作流程主要用于 Python 项目及其文档,但不仅限于此。它们都是 可复用的 GitHub Actions 工作流程。
集中工作流程存储库的原因
- 当然,可复用性:不需要更新数十个存储库,其中 95% 的工作流程是相同的
- 集中所有与自动化相关的依赖项:想想触发 dependabot 升级到所有依赖该操作的存储库的动作的点发布
指南
我不想复制粘贴、保持同步和维护另一个 N
个 CI/CD 文件在存储库的根目录。
因此,我的政策是:将每个存储库特定的配置移动到 pyproject.toml
文件中,或将令人作呕的细节隐藏在复用的工作流程中。
.github/workflows/docs.yaml
任务
-
自动修复拼写错误
-
优化图像
-
保持
.mailmap
最新 -
更新 Python 项目的依赖关系图
- 要求:
- 具有
pyproject.toml
文件的 Python 软件包
- 具有
- 要求:
-
构建基于 Sphinx 的文档并将其发布到 GitHub Pages
- 要求:
- 具有
pyproject.toml
文件的 Python 软件包 - 所有 Sphinx 依赖项位于
docs
额外依赖项组[project.optional-dependencies] docs = [ "furo == 2024.1.29", "myst-parser ~= 3.0.0", "sphinx >= 6", ... ]
- Sphinx 配置文件位于
docs/conf.py
- 具有
- 要求:
-
从
awesome-template
存储库同步 Awesome 项目
为什么有所有这些 requirements/*.txt
文件?
以 .github/workflows/lint.yaml
中的 lint-yaml
作业为例。这里我们只需要 yamllint
CLI。此 CLI 在 PyPi 上分发。因此,在执行之前,我们可以简单地运行以下步骤
- name: Install yamllint
run: |
pip install yamllint
相反,我们通过 requirements/yamllint.txt
文件 安装它。
为什么?因为我想要锁定 yamllint
的版本。通过锁定它,我使工作流程变得稳定、可预测和可重复。
那么为什么使用专用需求文件呢?我们为什么不直接添加版本?就像这样
- name: Install yamllint
run: |
pip install yamllint==1.35.1
这确实会锁定版本。但它要求维护者(我)跟踪新版本并手动更新版本字符串。这是一项大量的工作。而我比较懒惰。因此,这应该被自动化。
为了自动化这一点,我找到的唯一可行方法是依赖 dependabot。但 dependabot 不能在 run:
YAML 块中更新任意版本。它 仅支持 Python 项目的 requirements.txt
和 pyproject.toml
文件。
因此,为了在保持依赖项稳定的同时跟踪它们的新版本,我们在 requirements/*.txt
文件中硬编码了所有 Python 库和 CLI。所有都使用锁定版本。
对于需要一次性安装所有依赖项的情况,我们在根目录有一个 requirements.txt
文件,它引用了 requirements/
子文件夹中的所有文件。
权限和令牌
此存储库通过 GitHub actions 自动更新自己。它特别更新其 .github/workflows
中的自己的 YAML 文件。这是默认禁止的。因此,我们需要额外的权限。
通常,要为某些作业授予特殊权限,您会在工作流程文件中使用 permissions
参数。它看起来像这样
on: (...)
jobs:
my-job:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps: (...)
但是,contents: write
权限不允许写入 .github
子文件夹中的工作流程文件。有 actions: write
,但它只涵盖工作流程运行,不涵盖它们的 YAML 源文件。即使 permissions: write-all
也不起作用。因此,您不能使用 permissions
参数允许存储库的工作流程更新其自己的工作流程文件。
您最终总会遇到这种错误
! [remote rejected] branch_xxx -> branch_xxx (refusing to allow a GitHub App to create or update workflow `.github/workflows/my_workflow.yaml` without `workflows` permission)
error: failed to push some refs to 'https://github.com/kdeldycke/my-repo'
[!NOTE] 这也是为什么您的存储库设置 > 操作 > 通用 > 工作流程权限参数对此问题没有影响,即使设置了
读取和写入权限
:
为了绕过此限制,我们依赖自定义访问令牌。按照惯例,我们称它为 WORKFLOW_UPDATE_GITHUB_PAT
。它将在需要更改工作流程 YAML 文件的操作中使用,代替默认的 secrets.GITHUB_TOKEN
。
要创建此自定义 WORKFLOW_UPDATE_GITHUB_PAT
- 从您的 GitHub 用户,转到
设置
>开发者设置
>个人访问令牌
>精确令牌
- 单击
生成新令牌
按钮 - 选择一个良好的令牌名称,例如
workflow-self-update
,以便清楚地表达您的意图 - 选择
仅选择存储库
并列出需要更新其工作流程 YAML 文件的存储库 - 在
存储库权限
下拉菜单中设置内容
:访问: **读取和写入**
元数据
(必需):访问: **只读**
拉取请求
:访问: **读取和写入**
工作流程
:访问: **读取和写入**
[!NOTE] 这是唯一我可以控制
工作流程
权限的地方,该权限不受 YAML 文件中的permissions:
参数支持。
- 现在保存这些参数并复制
github_pat_XXXX
密码令牌 - 访问您的仓库 >
设置
>安全
>密钥和变量
>操作
>密钥
>仓库密钥
,然后点击新建仓库密钥
- 将您的密钥命名为
WORKFLOW_UPDATE_GITHUB_PAT
并将github_pat_XXXX
令牌复制到密钥
字段
现在重新运行您的操作,它们应该能够在不出现 拒绝允许 GitHub 应用创建或更新工作流程
错误的情况下更新 .github
文件夹中的工作流程文件。
发布管理
结果证明 发布工程是一项全职工作,充满了边缘情况。
Rust 有 cargo-dist
。Go 有……?但是 Python 没有这样的工具。
因此,我创建了一个 release.yaml
工作流程,它可以
- 从
pyproject.toml
提取项目元数据 - 生成所有提交 / 操作系统 / 架构 / CLI 入口点的构建矩阵
- 使用 Twine 构建 Python 轮
- 使用 Nuitka 编译所有 CLI 的二进制文件
- 在 Git 中标记发布提交
- 发布新版本到 PyPi
- 发布 GitHub 发布版
- 将其附加并重命名构建工件
变更日志
一个 详细的变更日志 可用。
使用于
查看这些项目以获取使用示例和灵感
Awesome Falsehood - 程序员相信的谬误。
Awesome Engineering Team Management - 如何从软件开发过渡到工程管理。
Awesome IAM - 云平台上的身份和访问管理知识。
Awesome Billing - 云平台上的计费和支付知识。
Meta Package Manager - 多个包管理器的统一 CLI。
Mail Deduplicate - 用于删除类似电子邮件的 CLI。
dotfiles - 针对 Python 开发的 macOS dotfiles。
Click Extra - Click 的额外着色和配置加载。
Wiki 机器人 - 提供维基百科功能,如摘要、标题搜索、位置API等。
workflows - 它本身。吃自己的狗粮。
股票分析 - 简单易用的股票基本技术分析界面。
GeneticTabler - 使用遗传算法的时间表调度器。
Excel Write - 在Excel文件中写入的优化方式。
如果您依赖这些脚本,请随时发送PR以将您的项目添加到此列表。
发布过程
发布过程和版本管理的所有步骤都自动在changelog.yaml
和release.yaml
工作流程中。
接下来要做的是
- 检查打开的
prepare-release
PR及其更改, - 点击
准备评审
按钮, - 点击
重新基和合并
按钮, - 让工作流程标记发布并将
main
分支设置回开发状态。
项目详情
下载文件
下载适合您平台文件的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。