简单自用的自动化AUR

一大堆作业

起因

我的日用系统从Windows切到Arch Linux已经小有一段时间了,过程中难免会遇到部分软件包无法满足我的需求以及部分在AUR的包不能及时跟上上游版本,所以打算托管一个PKGBUILD仓库,然后使用GitHub Action来完成日常的检查版本、构建相关包、推送到源仓库。

在此之前需要明确我的需求:

  • 仓库中主要包含与构建产物小、上游更新较频繁的包
  • 仓库中主要为满足我自己需求的、AUR中可能不存在的PKGBUILD

搜索了一下发现大家都主要是自动化构建AUR中存在的包,流程中很难加入自己的PKGBUILD;而且有的构建流程写得很死,我也没有相关经验所以看着很头疼。后来翻到了这位开发者的两个仓库:zaggash/archlinux-aurzaggash/gh-workflows,看过他的工作流后不禁称赞,不仅主打一个可复用性而且简单修改就能满足我的需求,算是我工作流的启蒙了。

因此我打算基于这两个仓库的工作流框架来自建AUR仓库。

搓轮子

目前的架构为:

  • 支持直接导入AUR的PKGBUILD(submodule形式引入)以及自定义PKGBUILD(需要自己打标签)
  • Renovate 负责监控部分包版本以及修改更新PKGBUILD中的版本信息
  • nvchecker用于补充监控部分包版本
  • GitHub Action作为自动化主体
  • 包存储选择了GitHub Releases与CloudFlare R2
  • (可选)r2-dir-list作为简单的仓库前端

Renovate

版本标签

Renovate的官方文档中其实就有一篇管理AUR的文章:Maintaining AUR packages with Renovate,但主要解决的是AUR维护者的日常版本更新问题,不过也提供了很好的例子来展现Renavate如何获取和更新版本。

在Renovate的配置文件中需要配置一个自定义的包管理器(因为没有AUR相关的预设包管理器)。绝大部分代码都是来自文档,我只修改matchStrings和添加了autoReplaceStringTemplate,都是为了一个目的:如果你pkgrel不为1时,更新pkgver后同时更新pkgrel为1。

1
2
3
4
5
6
7
8
9
10
11
12
13
"customManagers": [
{
"customType": "regex",
"fileMatch": [
"(^|/)PKGBUILD$"
],
"matchStrings": [
"pkgver=(?<currentValue>.*) # renovate: datasource=(?<datasource>.*) depName=(?<depName>.*)\\npkgrel=(?<pkgrel>.*)"
],
"extractVersionTemplate": "^v?(?<version>.*)$",
"autoReplaceStringTemplate": "pkgver={{{newValue}}} # renovate: datasource={{{datasource}}} depName={{{depName}}}\npkgrel=1"
}
]

然后你只需要在原有的PKGBUILD中的pkgver行添加注释作为标记,并且下一行为pkgrel:

1
2
pkgver=1.2.2 # renovate: datasource=github-tags depName=LiteLoaderQQNT/LiteLoaderQQNT
pkgrel=4

其中的datasource就是获取版本信息的来源,你可以使用Renovate预设的各种值以及自己编写custom源(我还是非常推荐all in custom源然后交给nvchecker来获取版本信息,nvchecker节会解释)。而depName可以理解为“包”的名字。你可以这样理解:在github-tags中有a、b、c不同的仓库,而你需要的只是b这个仓库的相关信息,所以你需要填写depName=b

自定义版本源

只有自定义包管理器还不行,你需要为Renovate的datasource提供版本信息的来源,所以下面来写一个自定义源,在动手前推荐看Renovate开发者的这篇博客,相比官方文档其可以说得上是手把手教学。

上文我有提到建议all in nvchecker,这里我稍微解释一下。如果你的各种PKGBUILD中包的上游并不统一(比如都来自a、b、c等平台而且都没有预设)并且你需要通过比较hack的方式来获取版本号(比如闭源软件),那么根据Renovate文档中提到的方式写一个自定义版本源,你就需要为不同的平台写一个不同的源而且那些hack的方式都无法实现。因此我选择了nvchecker来完成版本号的获取。

datasource对接nvcheher只需要这样:

1
2
3
4
5
6
7
8
"customDatasources": {
"nvchecker": {
"defaultRegistryUrlTemplate": "https://raw.githubusercontent.com/CAB233/myAUR/main/.github/new_ver.json",
"transformTemplates": [
"{ \"releases\": [{ \"version\": data.'{{packageName}}'.version }] }"
]
}
}

defaultRegistryUrlTemplate用于指向nvchecker生成的结果,可以是本地文件也可以是远程文件。transformTemplates用于将nvchecker的结果转换为Renovate能够识别的信息(如果你使用原始的nvchecker,则转换规则不需要改动)。

包规则

在这里你可以对监控的一堆包进行针对性设置,例如你可以指定a包仅每个月检查一次更新、b包需要你的审阅后才能更新。更多设置你可以查阅Renovate文档中关于packageRules的配置选项。

我主要配置了自动更新,不需要审阅和测试直接修改版本信息然后提交到仓库里,实现无人监守自动化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
"packageRules": [
{
"description": "自动合并 submodule 更新",
"matchManagers": [
"git-submodules"
],
"matchDatasources": [
"git-refs"
],
"enabled": true,
"automerge": true,
"ignoreTests": true,
"automergeType": "branch"
},
{
"description": "自动合并自定义 PKGBUILD 更新",
"matchDatasources": [
"github-tags",
"custom.nvchecker"
],
"automerge": true,
"ignoreTests": true,
"automergeType": "branch"
}
]

nvchecker

调试、配置和使用都非常简单,你只需要参考官方文档根据自己的需求配置即可。可以参考我工作流中的配置

因为我想确保nvchecker在检查结束版本信息后Renovate能够第一时间获取并更新(如果是通过GitHub Apps引入的Renovate,最差的情况是Renovate和nvchecker同时运行计划任务,而Renovate开始得稍微早一点导致nvcheker获取到的新版本信息要在下一次计划任务后Renovate才会更新PKGBUILD),所以我将nvchecker与Renovate放在一起并且Renovate使用了自托管方案。

后期我考虑直接将nvchecker的结果直接作为Renovate的输入,这样就能少一次commit。

Workflows

云原生害人不浅,调试老费劲了

我只在zaggash他的工作流基础上做了些修改,舍弃了可复用性、写死了部分变量(变成了自己讨厌的模样)。

部分改进:

  • 添加pacman-contrib包,使用updpkgsums而不是makepkg -g更新文件校验值,因为后者如果PKGBUILD没有在最后一行换行则有可能无法更新校验值
  • 使用 yay 缓存减少构建时间
  • 引入自己的仓库,补全自有仓库的内部依赖(总感觉yay在选择安装存在于自有AUR与官方AUR中的包时有奇怪的依赖关系)

部分坑:

  • 要使用没有密码的GPG私钥,因为在build_packages环节使用数组进行构建,如果使用crazy-max/ghaction-import-gpg action来导入有密码的私钥,就相当于在一个系统里多次导入删除(?),总之要相信前人的智慧。

包存储

即使我现在使用R2作为存储后端,我也还是推荐使用GitHub Releases存储更为方便(如果你的网络条件良好)。不仅在构建时自己引入自己时不会触发奇怪的速率限制,而且后期可以通过x86_64aarch64等tag来实现多架构、多平台支持。

关于R2使用的actionryand56/r2-upload-action,其中的keep-file-fresh功能是我第一次给人提功能性PR,而且还是在我丝毫不懂js然后用GPT帮我写的情况下提的,感谢这位开发者的不杀之恩🙏。

小结

我的相关仓库在这CAB233/myAUR,欢迎使用和提出意见。

已知问题

  • 构建失败的包会从源仓库里直接消失(不论是R2还是Releases存储方案)。
  • 第一次引入PKGBUILD中若引用自有仓库的依赖,需要多次构建才能满足依赖。
  • 更新yay缓存需要手动删除旧缓存、触发新构建。

简短的使用方法

  1. 所有相关的文件都在.github文件夹中,其中的new_ver.json可以删去

  2. 其他文件中需要你自己根据需求修改被我写死的变量,例如源仓库名称

  3. 手动触发一次yay缓存构建和nvchecker结果输出

  4. 如果你不在意nvchecker与Renovate之间的更新延迟,可以直接使用GitHub Apps版本的Renovate,然后renovate.json中的"onboarding""requireConfig""username""gitAuthor""platform""repositories"这些字段都可以删去

  5. 在仓库根目录下使用git submodule引入AUR现有包(这样只有PKGBUILD是最新的,版本并不一定是上游最新的)或者新建个文件夹然后塞入自己的PKGBUILD

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 文件结构
    .
    ├── aliyunpan-odomu-bin
    │   ├── alixby.desktop
    │   ├── app.asar
    │   └── PKGBUILD
    ├── cachyos-keyring
       ├── cachyos-keyring.install
       └── PKGBUILD
  6. 🎉开始自动之旅吧

  • 标题: 简单自用的自动化AUR
  • 作者: 一大堆作业
  • 创建于 : 2024-10-06 00:00:00
  • 更新于 : 2024-10-06 00:00:00
  • 链接: https://blog.zuoye.win/post/jian-dan-zi-yong-de-zi-dong-hua-aur/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论