2021/11/28

自从我搭建完软件源之后准备做一个自动从 AUR 构建指定的包并更新到软件源的东西。我希望它包含以下几个功能:

  • 能对接我现在的软件源系统
  • 构建时候没有依赖之类的问题
  • 如果软件源里面已经有了相同版本,那就不重复构建了。就算重复构建了也不重复上传到服务器
  • 不仅能构建 x86_64 的包,还要支持 aarch64

首先呢我是找了一些现成的解决方案,有的使用 yay 来构建软件包,有的直接使用 makepkg。但是大体上都是基于以下这两个仓库派生出的

于是我也 fork 了这两个仓库,直接在这之上修改。

制作 build-aur-action 的 Docker 模板

我是基于 vifly / arch-build 中的修改版 Action 来修改的。这里面的 Docker 镜像大概做以下几件事:镜像构建时,安装 gitbase-devel。镜像每次运行时,添加 ArchLinuxCN 源并且从里面安装 yay,再创建非 Root 用户并用 yay 安装指定的包,最后拿 yay 安装之前的那个构建包。

然后我发现这个 Docker 有一些问题,比如说安装 yay 以及之前的步骤都可以在 Dockerfile 里面做,没必要等到构建完。以及 yay 如果 -S 一个源里有的包会直接从源安装,而不是从 AUR 构建了。这个可以用 -a 开关解决。

我在 pacman.conf 中添加了竹林里有冰大佬的源以及我自己的源,以便提供一些类似于 deepin-wine 之类的依赖包。然后构建还是通过 yay,但是现在加上了 -a 开关来指定只从 AUR 获取

编写 Action 的 YAML

YAML 也是基于 vifly / arch-build 的修改的。这里使用了 matrix 来实现并行构建。为了实现检查包是否存在,我给 arch-repo-builder 添加了一个检查文件存在的接口。然后首先下载 PKGBUILD 并且 source 它,使用里面的变量以及默认的 x86_64 架构生成一个大概的包将来会是的文件名,并且询问服务器这个文件是否存在。要是存在的话,就不继续构建了。

然后就是调用刚才的方法在 Docker 里面构建安装并且拿包,然后通过 ls 获取包真实的名字,存入 step 的 output 里面,再向服务器请求一次是否存在。不存在的话再继续上传和调用接口。

如果你们的源有不一样的方法来提交包,那就把下面这三个步骤改了就可以。当然判断包是否存在的接口也需要改呢

      - name: deploy file
        if: ${{ steps.isNeed.outputs.isNeed == 'false' && steps.isNeed2.outputs.isNeed == 'false' }}
        uses: wlixcc/SFTP-Deploy-Action@v1.0
        with:
          username: 'repo-builder'
          server: ${{ secrets.REPO_BUILDER_HOST }}
          ssh_private_key: ${{ secrets.REPO_BUILDER_PRIVKEY }}
          local_path: ${{ matrix.repos }}/${{ steps.pkgname.outputs.pkgname }}
          remote_path: '/home/repo-builder/tmp'

      - run: curl -u ${{ secrets.REPO_BUILDER_AUTH }} ${{ secrets.REPO_BUILDER_API }}/api/add-package/${{ steps.pkgname.outputs.pkgname }}
        if: ${{ steps.isNeed.outputs.isNeed == 'false' && steps.isNeed2.outputs.isNeed == 'false' }}

      - run: curl -u ${{ secrets.REPO_BUILDER_AUTH }} ${{ secrets.REPO_BUILDER_API }}/api/queue

其实最后一步请求队列信息是可选的啦

增加构建 aarch64 源的包的支持

因为我手机上也有一个 chroot 的 Arch Linux 嘛,我希望这个 Actions 可以顺便帮我构建 aarch64 架构的一些包。

首先因为架构不一样,不能直接用 yay 直接安装的方式了,需要先手动 clone AUR 的 git,然后可以先 source 一下 PKGBUILD,然后通过下面的命令把所有的依赖都通过 yay 来解决

yay -S --noconfirm --needed --asdeps "${makedepends[@]}" "${depends[@]}"

然后打包的命令需要改成

CARCH=aarch64 makepkg -sfA

这样差不多就好了

处理一个 pkgbase 多个包的情况

之前通过 $(ls *-*.pkg.tar.*) 获取包的名字的方法,如果有多个包会得到空白字符隔开的值。所以我们可以通过把通配符变得更详细一些来只获取我们需要的包。

我们可以在「生成一个大概的包将来会是的文件名」那个步骤,把 PKGBUILD 中 pkgname pkgver pkgrel 之类的都存在输出里

source PKGBUILD
echo ::set-output name=pkgname::$pkgname
echo ::set-output name=pkgver::$pkgver
echo ::set-output name=pkgrel::$pkgrel

哦对,在 GitHub Actions 里面可以通过在控制台中输出 ::set-output name=<key>::<value> 这样的字符串来指定 step 的输出,这个输出可以在下面的步骤里直接使用

然后我们的 ls 命令可以改成

echo ::set-output name=pkgname::$(ls ${{ steps.isNeed.outputs.pkgname }}-${{ steps.isNeed.outputs.pkgver }}-${{ steps.isNeed.outputs.pkgrel }}-*.pkg.tar.*)

这样就解决了

关于这个源

我的电脑上大概是有以下三个个人源:竹林里有冰源光量子源我自己的源。我的源应该是准备作为前两个源的补充,作为 icalingua-beta 包的发布源,以及放一些在 aarch64 架构上用到的包。

可以通过在 /etc/pacman.conf 中写入以下内容来添加

[Clansty]
SigLevel = Never
Server = https://dl.lwqwq.com/repo/$arch

最终成品

Clansty / arch-build 可以直接 fork 这个下来修改

Clansty / build-aur-action 这是使用的 Actions 构建 step 模板

如果想要搭建和我一样的 OneDrive 仓库元数据构建服务器,那么可以使用这里的 docker-compose.yaml,详见上一篇文章。

Arch-build 仓库需要设置以下 Secrets:

REPO_BUILDER_API: 应该是一个 https://部署好的 API 访问地址,不带末尾 / 的
REPO_BUILDER_AUTH: 应该是一个 `用户名:密码`,不过如果你没有设置 basicauth,可以修改 Actions 的 YAML,把 curl 中的 -u 参数删除
REPO_BUILDER_HOST: 可以直接 SSH 上的地址
REPO_BUILDER_PRIVKEY: SSH 使用的私钥。用户名和上传的位置写在 Actions YAML 中
来评论叭~
评论输入区域