简介

Gitea Actions 是 Gitea 提供的一项流水线服务。它基于 Github Actions 的配置文件和语法,提供了与 Github Actions 相似的 CI/CD 体验。

我这边已经使用 Gitea 很多年了,大部分私人代码都存放于自己的 Gitea 实例上。在前面的文章中也提到过,我这边使用的 CI/CD 系统是 Jenkins。那么为什么已经有了 Jenkins 还需要使用 Gitea Actions 做 CI/CD 呢?

在我看来,Jenkins 是一个复杂且功能完善的系统,而 Gitea Actions 则更为简洁。对于一些简单的流水线应用来说,Gitea Actions 可能更为方便。同时,Gitea Actions 也能很好地与 Github Actions 相互兼容。这就意味着两边的代码库可以共享同一份 CI/CD 配置,而无需来回转换。

架构与配置

Gitea Actions 依赖于 Gitea Act Runner 服务提供对应的流水线构建能力。Act Runner 实际上是一个流水线运行工具,它允许你在本地解析并运行对应的流水线。而 Gitea 在其基础上添加了连接到 Gitea 实例的功能。这也就将 Gitea 代码仓库与 Act Runner 流水线打通,实现了整套 CI/CD 的功能。

在之前的文章中已经提到过,构建相关的服务实际上是运行在一个 K8S 集群内的。对于 Jenkins 来说,其内置的 Kubernetes 插件可以按需拉起构建用的容器,再在里面运行对应的流水线。而对于 Gitea 来说,情况又有所不同。

Gitea 在运行时会读取流水线配置文件,根据其中的 runs-on 字段做标签匹配,最后决定在哪一个 Runner 上运行对应的指令。而 Gitea Act Runner 在注册时会默认使用这样的标签注册到 Gitea ubuntu-latest:docker://node:16-bullseye。后面的 docker://image:tag 指示了 Act Runner 要拉起一个容器,其镜像为 image:tag,而之后的流水线动作都会在这个镜像里面运行。

考虑到我们要在 K8s 容器内运行 Act Runner,而如果 Act Runner 还要拉起一个镜像的话,那么势必会出现 Docker in Docker (dind) 的架构。而这种架构是不推荐使用的。

如果放弃 Docker,那么剩下的路就只有一条了:直接在 Act Runner 中运行对应的流水线。如果需要打包容器镜像,那么就使用 Buildah 来打包。

还好,Gitea Act Runner 提供了不依赖 Docker 的启动方式。只需要将标签设置为 ubuntu-22.04:host 这种,后面添加一个 :host 标签,即可令任务直接运行在主机上。

当然,这种架构不是没有问题的。直接在主机上运行的隔离性不佳,可能造成脏工作空间,或是有安全问题。不过考虑到这个 Runner 只运行我的代码库中的代码,第二个问题倒也不是那么大。

构建容器镜像

前面已经明确了我们的需求,那么接下来就是编写 Containerfile 构建容器镜像了。基础镜像需要的内容如下:

  • Act Runner: 这个是运行器的本体;
  • NodeJS: 如果你不使用其他脚本,可以不装。但是 Github Actions 下的 Checkout 等脚本都依赖了 NodeJS。所以为了保持通用性,这还是得装上。
  • Buildah: 用于打包容器镜像。如果你不做容器镜像构建,也可以不装。
  • Git: 用于代码检出。

具体镜像文件如下:

FROM docker.io/library/alpine

# RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/*
RUN apk add --no-cache libstdc++ zip zstd gzip curl wget git tzdata buildah ca-certificates fuse-overlayfs netavark iptables
RUN sed -i 's/#default_rootless_network_cmd = "pasta"/default_rootless_network_cmd = "slirp4netns"/g' /etc/containers/containers.conf
COPY run.sh prepare.sh /usr/local/bin/

VOLUME /var/lib/containers
VOLUME /opt
ENTRYPOINT ["/usr/local/bin/run.sh"]

这里的 run.sh 就是官方库中的 run.sh

有几个坑点需要注意:

  1. Builadh 5 版本开始,非 root 用户下默认使用的是 pasta 网络。我这里这个网络起来有点问题,故在第 5 行处手动改为了原有的 slirp4netns;
  2. 对于 Buildah 的镜像,需要手动声明 VOLUME /var/lib/containers,且需要启用特权模式才能使用 fuse-overlayfs 。具体请参见 这个 Issue

同时,我这里没有直接在 alpine 中安装 Act Runner 和 NodeJS 依赖。这是因为NodeJS 装上去之后镜像太大了。我这里选择了在 Entrypoint 初始化时下载这些依赖:

#!/bin/sh
mkdir -p /opt
cd /opt

NODE_VERSION=node-v24.12.0-linux-x64-musl
export PATH=$PATH:/opt:/opt/$NODE_VERSION/bin

if [ ! -d $NODE_VERSION ]; then
    wget https://unofficial-builds.nodejs.org/download/release/v24.12.0/$NODE_VERSION.tar.xz -O node.tar.xz
    tar xf node.tar.xz
    rm node.tar.xz
fi

if [ ! -f act_runner ]; then
    wget https://gitea.com/gitea/act_runner/releases/download/v0.2.13/act_runner-0.2.13-linux-amd64 -O act_runner
    chmod 755 act_runner
fi

这里还有个坑点:官方的 nodejs 用的是 glibc,而不是 musl。直接在 alpine 镜像中运行官方的 nodejs 是不可能成功的。所以这里用的是 unofficial-builds 中的构建。

环境变量的配置

参考官方文档配置就行了:

         env:
            - name: GITEA_INSTANCE_URL
              value: "http://example.org/"
            - name: GITEA_RUNNER_REGISTRATION_TOKEN
              value: "xxxx"
            - name: GITEA_RUNNER_NAME
              value: "default"
            - name: GITEA_RUNNER_LABELS
              value: "buildah:host"
          securityContext:
            privileged: true

总结

Gitea Actions 作为 Jenkins 的轻量替代还是很好用的。对于 Unity 打包来说,Jenkins 还是无法替代的,但是对于常见的 docker 镜像构建来说,直接用 Actions 会更加方便。

分类: 未分类

0 条评论

发表回复

Avatar placeholder

您的邮箱地址不会被公开。 必填项已用 * 标注