最近折腾了一套 AUR 自动构建脚本,用来把常用的 AUR 包编译成自己的 pacman 仓库,并同步到 Cloudflare R2。
整体思路并不复杂:GitHub Actions / 容器负责构建,pikaur 负责拉取和编译 AUR 包,repo-add 负责生成仓库数据库,最后用 rclone 把产物上传到 R2。
设计目标
这套脚本主要解决几个问题:
- 不想在本机反复编译大型 AUR 包
- 多台 Arch 设备可以共用同一个二进制仓库
- 构建产物需要带签名,方便 pacman 直接校验
- 仓库文件要能低成本公开访问
- 构建脚本和密钥配置要尽量自动化
最终效果是:只要脚本跑完,R2 上会生成完整的 pacman 仓库目录,客户端添加源之后就可以像官方源一样安装。
脚本结构
脚本大致分成几块:
1 | script/ |
核心入口是 main.zsh,它负责完成完整流水线:
1 | 初始化 pacman / makepkg |
构建环境初始化
脚本会先启用 multilib,再把自定义的 MAKEPKG_CONF 写入 /etc/makepkg.conf。
这里主要配置:
CFLAGS/CXXFLAGS:按机器架构优化MAKEFLAGS:自动使用多线程编译BUILDENV:开启包签名,关闭不需要的构建特性PKGEXT:统一使用pkg.tar.zstCOMPRESSZST:提高压缩效率
然后创建一个独立的 aur-build 用户,所有 AUR 构建都在这个用户下执行,避免直接用 root 跑 makepkg。
包构建逻辑
普通 AUR 包可以直接放在 packages/包名/PKGBUILD 下,由 pikaur 处理依赖和构建。
对于需要特殊处理的包,则可以单独写 build.zsh。例如某些官方包需要改 PKGBUILD、禁用 strip 或调整 makepkg 配置,就可以在独立脚本里完成。
这种设计的好处是:
- 普通包保持简单
- 特殊包可以单独定制
- 构建失败不会影响脚本结构
- 后续添加新包只需要新增目录
仓库数据库生成
构建完成后,脚本不会简单地在旧数据库上继续追加,而是先清理再重建:
1 | 删除 debug 包 |
这样可以避免几个常见问题:
- 旧版本包长期堆积
- 数据库里残留不存在的包
- debug 包被意外加入仓库
- 多次构建后仓库状态不一致
对个人仓库来说,这种“从当前产物重建数据库”的方式更可控。
上传到 Cloudflare R2
上传部分使用 rclone 的 S3 后端对接 Cloudflare R2。
配置不写入 rclone 配置文件,而是通过环境变量传入:
1 | RCLONE_CONFIG_R2_TYPE=s3 |
这样有两个优点:
- CI 环境里更容易注入密钥
- 不会在命令参数里直接暴露 access key
脚本还会把 R2 endpoint 处理成 account-level endpoint,再把 bucket 名称放进路径里。这是为了避免 bucket-specific endpoint 在 list / delete / sync 场景下出现兼容问题。
相比原始方案的改进
这版脚本主要做了这些调整。
1️⃣ 上传方式改为 rclone + R2
原始方案更偏向固定对象存储上传流程,我这里统一改成 rclone sync。
优点是:
- 本地目录和远端仓库保持一致
- 删除旧文件更自然
- R2 / S3 兼容存储都容易迁移
- CI 日志更容易看出同步了哪些文件
2️⃣ R2 配置集中到 script.conf
所有 R2 相关配置都放在同一个配置文件中,包括:
- bucket 名称
- endpoint
- 仓库上传前缀
- 脚本备份路径
- access key
- secret key
这样脚本本身只负责流程,具体环境差异都交给配置文件处理。
3️⃣ 兼容无密码 GPG 私钥
原始脚本会预设 GPG passphrase,适合带密码的私钥。
我的场景里使用的是无密码私钥,所以去掉了 gpg-preset-passphrase 相关逻辑,只保留:
1 | pacman-key 导入并信任 |
流程更短,也更符合当前使用方式。
4️⃣ 仓库数据库改为完全重建
直接在旧数据库上追加包,时间久了容易留下脏状态。
现在每次上传前都会:
- 清理 debug 包
- 使用
paccache -k1保留最新版 - 删除旧数据库文件
- 对当前包目录重新执行
repo-add
这样 R2 上的仓库更像一次干净发布,而不是不断叠加的历史目录。
5️⃣ 构建脚本支持加密备份
upload_script.zsh 会用 7z 把脚本目录打包,并开启文件名加密:
1 | 7z a /tmp/script.7z -mhe=on -p"$PASSWORD" ./ |
然后把加密包上传到 R2 的指定路径。
这样即使 CI 环境临时丢失,也可以从对象存储里恢复脚本配置。当然,真正敏感的 token 和私钥仍然建议放在 CI secret 里,不要长期明文落盘。
客户端使用方式
仓库发布后,在客户端导入 GPG key,然后添加 pacman 源:
1 | [custom] |
之后就可以直接安装:
1 | sudo pacman -Syu |
如果是私有仓库,也可以把 R2 前面接 Cloudflare Access 或者只在内网环境使用。
总结
这套脚本的重点不是“能不能构建 AUR”,而是把 AUR 构建变成一个稳定的发布流程:
- 构建环境可重复
- 包签名自动完成
- 仓库数据库保持干净
- 旧包自动清理
- R2 上传可同步、可恢复
- 配置和流程分离
对于只有几台 Arch 设备的个人用户来说,这种方式已经足够轻量;对于经常折腾 AUR 包、又不想在本机反复编译的人来说,也能省下不少时间。
