autopackage
Nightly, directory-driven Arch package builder for Gitea CI.
Every top-level folder in this repo is a package. The nightly job
(.gitea/workflows/nightly.yml) builds them all
in an archlinux:latest container and publishes the resulting
*.pkg.tar.zst files to a Gitea Arch package
registry. Gitea keeps the pacman
database up to date automatically — there is no repo-add step.
How a folder is classified
For a folder foo/:
Contents of foo/ |
Treated as | What happens |
|---|---|---|
Contains a PKGBUILD |
custom | Built as-is from the folder. |
No PKGBUILD |
AUR | https://aur.archlinux.org/foo.git is cloned, then overrides/patches from foo/ are applied. |
AUR packages
The folder name is the AUR package name. The simplest AUR package is a
folder that just contains a .gitkeep (git won't track an empty directory):
openrgb-git/
.gitkeep
To customize an AUR package without forking the whole PKGBUILD, drop files in
the folder:
- Patches — any
*.patch/*.difffiles are applied (in sorted order) on top of the freshly cloned AUR repo.git applyis tried first, thenpatch -Np1. - Overrides — any other file (e.g. an extra source file, a
.installscript) is copied into the clone, replacing a file of the same name.
Note: if you add a full
PKGBUILDto the folder it becomes a custom package and the AUR repo is no longer cloned. Use patches/overrides to tweak an AUR package.
Example AUR package with a patch:
openrgb-git/
.gitkeep
0001-fix-udev-rules.patch
Custom packages
A folder with its own PKGBUILD (plus any local sources) is built directly:
my-thing/
PKGBUILD
my-thing.install
some-source.tar.gz
Publishing / consuming
Packages are uploaded to {GITEA_URL}/api/packages/{owner}/arch/{repo} where
{repo} defaults to arch (configurable via AUTOPKG_REPO).
Add this to /etc/pacman.conf on client machines (replace the host/owner):
[arch]
SigLevel = Optional TrustAll
Server = https://git.example.com/api/packages/<owner>/arch/arch/$arch
SigLevel = Optional TrustAllis used because packages are unsigned by default. To sign them, set up a GPG key on the runner and pass--sign(the.sigfiles are uploaded automatically); then you can switch to a stricterSigLevel.
CI configuration
The workflow needs one secret:
PACKAGE_TOKEN— a Gitea access token with thewrite:packagescope (andread:package). Create it under Settings → Applications → Generate New Token, then add it under the repo's Settings → Actions → Secrets.
Everything else is derived from built-in Gitea Actions variables
(GITHUB_SERVER_URL, GITHUB_REPOSITORY_OWNER, github.actor).
The job runs nightly at 03:30 UTC and can also be triggered manually
(workflow_dispatch) with optional only (subset of package dirs) and
replace inputs.
Running locally
# Dry run: show what would be built/published
./autopackage.py --dry-run
# Build a subset without publishing
./autopackage.py --only openrgb-git paru --no-publish
# Build everything and publish to a registry
AUTOPKG_REGISTRY_URL=https://git.example.com \
AUTOPKG_OWNER=joe \
AUTOPKG_TOKEN=xxxxxxxx \
./autopackage.py --keep-going
makepkg must run as a non-root user with sudo available for dependency
installation. Builds happen in ./.build/ (gitignored).
Useful flags
| Flag | Purpose |
|---|---|
--only NAME ... |
Build just these package dirs. |
--no-publish |
Build only; skip uploads. |
--dry-run |
Print actions without running them. |
--cleanbuild |
Pass --cleanbuild to makepkg. |
--sign |
Sign packages and upload .sig files. |
--replace |
Delete + re-upload on a version clash (HTTP 409). |
--keep-going |
Continue if a package fails. |
Config can also come from env vars: AUTOPKG_REGISTRY_URL, AUTOPKG_OWNER,
AUTOPKG_REPO, AUTOPKG_USER, AUTOPKG_TOKEN, AUTOPKG_REPLACE.
Ignoring folders
Top-level dirs .git, .gitea, .github, .build, scripts, dist and
__pycache__ are never treated as packages. Add more (one name per line) in a
.autopackageignore file at the repo root.