跳至主要内容
版本:1.22.3

Gitea Actions 的设计

Gitea Actions 包含多个组件。本文档将对它们进行单独描述。

Act

项目 nektos/act 是一个很棒的工具,它可以让您在本地运行 GitHub Actions。我们受此启发,并想知道是否有可能为 Gitea 运行 actions。

但是,虽然 nektos/act 被设计为一个命令行工具,但我们真正需要的是一个 Go 库,它需要针对 Gitea 进行修改。所以我们把它 fork 成了 gitea/act

这是一个软 fork,它将定期跟随上游。虽然添加了一些自定义提交,但我们将尽力避免对原始代码进行过多更改。

fork 后的 act 只是一个针对 Gitea 特定用途的 shim 或适配器。已经进行了一些额外的提交,例如

  • 将执行日志输出到记录器挂钩,以便它们可以报告给 Gitea
  • 禁用 GraphQL URL,因为 Gitea 不支持它
  • 为每个作业启动一个新的容器,而不是重复使用以确保隔离。

这些修改没有理由合并到上游。如果用户只想在本地运行受信任的 actions,它们就没有意义。

但是,将来可能会出现重叠,例如两个项目都需要进行的错误修复或新功能。在这种情况下,我们将把更改贡献回上游存储库。

Act 运行器

Gitea 的运行器称为 act 运行器,因为它基于 act。

与其他 CI 运行器一样,我们将其设计为 Gitea 的外部部分,这意味着它应该在与 Gitea 不同的服务器上运行。

为了确保运行器连接到正确的 Gitea 实例,我们需要使用令牌将其注册。此外,运行器将向 Gitea 介绍自己,并通过报告其标签来声明它可以运行哪些类型的作业。

之前,我们提到工作流文件中的 runs-on: ubuntu-latest 意味着该作业将在具有 ubuntu-latest 标签的运行器上运行。但是运行器如何知道要运行 ubuntu-latest?答案在于将标签映射到环境。这就是为什么在注册期间添加自定义标签时,需要输入一些复杂的内容,例如 my_custom_label:docker://centos:7。这意味着运行器可以获取需要在 my_custom_label 上运行的作业,它将通过使用镜像 centos:7 的 docker 容器来运行它。

不过,Docker 不是唯一的选择。act 还支持直接在主机上运行作业。这是通过诸如 linux_arm:host 之类的标签实现的。此标签表示运行器可以获取需要在 linux_arm 上运行的作业,并直接在主机上运行它。

标签的设计遵循格式 label[:schema[:args]]。如果省略了 schema,则默认为 host。所以,

  • my_custom_label:docker://node:18:使用 node:18 Docker 镜像运行用 my_custom_label 标记的作业。
  • my_custom_label:host:直接在主机上运行用 my_custom_label 标记的作业。
  • my_custom_label:与 my_custom_label:host 相同。
  • my_custom_label:vm:ubuntu-latest: (仅示例,未实现) 使用具有 ubuntu-latest ISO 的虚拟机运行用 my_custom_label 标记的作业。

通信协议

由于 act 运行器是 Gitea 的独立部分,我们需要一个协议让运行器与 Gitea 实例通信。但是,我们认为在新的端口上监听 Gitea 不是一个好主意。相反,我们希望重用 HTTP 端口,这意味着我们需要一个与 HTTP 兼容的协议。我们选择使用 gRPC over HTTP。

我们使用 actions-proto-defactions-proto-go 将它们连接起来。有关 gRPC 的更多信息,请访问 其网站

网络架构

让我们检查一下整体网络架构。这将帮助您解决一些问题,并解释为什么使用 Gitea 实例的环回地址注册运行器是一个糟糕的想法。

network

图片中标记了四个网络连接,箭头方向表示建立连接的方向。

连接 1,act 运行器到 Gitea 实例

act 运行器必须能够连接到 Gitea 以接收任务并发送回执行结果。

连接 2,作业容器到 Gitea 实例

作业容器与运行器具有不同的网络命名空间,即使它们在同一台机器上。他们需要连接到 Gitea 以获取代码,例如,如果工作流中包含 actions/checkout@v4。获取代码并非总是运行某些作业所必需的,但在大多数情况下都是必需的。

如果您使用环回地址注册运行器,则运行器可以在同一台机器上连接到 Gitea。但是,如果作业容器尝试从 localhost 获取代码,它将失败,因为 Gitea 不在同一个容器中。

连接 3,act 运行器到互联网

当您使用诸如 actions/checkout@v4 之类的 actions 时,act 运行器将下载脚本,而不是作业容器。默认情况下,它从 github.com 下载,因此它需要访问互联网。如果您将 DEFAULT_ACTIONS_URL 配置为 self,那么它将默认从您的 Gitea 实例下载。然后,它在下载 action 本身时不会连接到互联网。它默认还会从 Docker Hub 下载一些 docker 镜像,这也需要互联网访问。

但是,互联网访问并非严格必需。您可以配置您的 Gitea 实例从您的内联网设施获取 actions 或镜像。

事实上,您的 Gitea 实例可以充当 actions 市场和镜像仓库。您可以将 actions 存储库从 GitHub 镜像到您的 Gitea 实例,并将其作为正常使用。并且 Gitea 容器仓库 可以用作 Docker 镜像仓库。

连接 4,作业容器到互联网

当使用诸如 actions/setup-go@v5 之类的 actions 时,可能需要从互联网下载资源以在作业容器中设置 Go 语言环境。因此,这些 actions 的成功完成需要访问互联网。

但是,这也是可选的。您可以使用您自己的自定义 actions 来避免依赖于互联网访问,或者您可以使用您打包的 Docker 镜像以安装所有依赖项来运行作业。

总结

使用 Gitea Actions 只需要确保运行器可以连接到 Gitea 实例。互联网访问是可选的,但如果没有它,则需要做一些额外的工作。换句话说:运行器在可以自己查询互联网时工作效果最佳,但您不需要将其暴露给互联网(无论哪种方向)。

如果您在使用 Gitea Actions 时遇到任何网络问题,希望上面的图片可以帮助您解决这些问题。