跳转到主要内容

⚙️ GitHub Actions的CLI助手 + 可重用的工作流

项目描述

gha-utils CLI + 可复用工作流程

Last release Python versions Type checked with mypy Unittests status Coverage status

多亏了这个项目,我能够 每天只需点击两次即可发布多个 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.txtpyproject.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 工作流程,它可以

  1. pyproject.toml 提取项目元数据
  2. 生成所有提交 / 操作系统 / 架构 / CLI 入口点的构建矩阵
  3. 使用 Twine 构建 Python 轮
  4. 使用 Nuitka 编译所有 CLI 的二进制文件
  5. 在 Git 中标记发布提交
  6. 发布新版本到 PyPi
  7. 发布 GitHub 发布版
  8. 将其附加并重命名构建工件

变更日志

一个 详细的变更日志 可用。

使用于

查看这些项目以获取使用示例和灵感

如果您依赖这些脚本,请随时发送PR以将您的项目添加到此列表。

发布过程

发布过程和版本管理的所有步骤都自动在changelog.yamlrelease.yaml工作流程中。

接下来要做的是

  • 检查打开的prepare-release PR及其更改,
  • 点击准备评审按钮,
  • 点击重新基和合并按钮,
  • 让工作流程标记发布并将main分支设置回开发状态。

项目详情


下载文件

下载适合您平台文件的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分发

gha_utils-4.6.0.tar.gz (37.7 kB 查看哈希值)

上传时间

构建分发

gha_utils-4.6.0-py3-none-any.whl (29.8 kB 查看哈希值)

上传时间 Python 3

由...