Update process
update-pkg.sh updates one package. check-all.sh --update runs it for every package with a new version, and the workflow splits the same update into prepare, verify and publish, see Prepare and publish.
Time limits
Section titled “Time limits”Outside --update, check-all.sh gives each package 120 seconds for check-update.sh and 300 seconds each for update-pkg.sh, verify-pkg.sh and publish-pkg.sh. timeout ends the script with everything it started, and the package gets check_failed: timed out after 120 s or update_failed: timed out after 300 s, with the URL of the request that was running, as in check_failed: https://github.com/owner/repo.git: timed out after 120 s. AURTOMATOR_CHECK_TIMEOUT and AURTOMATOR_UPDATE_TIMEOUT change the limits. --update has none, because it runs on a terminal, where git and ssh can ask for a passphrase.
A check that fails before its limit runs once more after all the other packages and a pause of 60 seconds, AURTOMATOR_RECHECK_DELAY, and the second result counts. A check that ran out of time, or failed on a silent host, runs once, so a run without network does not take twice as long.
A check run starts no check after 20 minutes, AURTOMATOR_CHECK_BUDGET, so its job ends within 30, and a package it did not reach gets check_failed: the check ran out of its 20 minutes in this run. Each run of the workflow starts the loop one package later, so slow hosts cannot hold back the same packages in every run.
A host that times out without any answer is silent for the rest of the run: every later request to it fails at once with <url>: <host> did not answer earlier in this run, so a silent host costs one check, whatever the number of its packages. A check that runs out of time during a request to a host makes it silent when one more HEAD request of 10 seconds gets no answer either. A refused connection, a failed DNS lookup, an HTTP error, an answer that stops halfway and a redirect to a silent host do not. A URL with a user name or a port, such as https://git.example.com:8443/, never makes its host silent, since curl contacts another host or port than the bare name.
Arguments
Section titled “Arguments”update-pkg.sh <package-name> <new-version> [--asset <value>] [--arch-out <arches>] [--dry-run] [--prepare <dir>]verify-pkg.sh <package-name> <version> <prepared-dir> [--asset <value>] [--arch-out <arches>]publish-pkg.sh <package-name> <version> <prepared-dir> [--asset <value>] [--arch-out <arches>] [--dry-run]check-asset.sh <package-name> <pkgver>check-arch.sh <package-name> <version> [--asset <value>]check-all.sh [--update | --prepare <dir> | --verify <dir> | --publish <dir>] [--dry-run]Step-by-step
Section titled “Step-by-step”- Read
.aurtomator.confas data, see Configuration file. In CI,GIT_AUTHOR_NAME,GIT_AUTHOR_EMAILandGPG_KEY_IDcome from the workflow. - Clone
ssh://aur@aur.archlinux.org/<package-name>.gitafter 2 seconds, with up to 3 attempts 5 seconds apart. A clone without a PKGBUILD stops the update. - Reset
mastertoorigin/masterwhen the clone lands on a detachedHEAD, so the push is a fast-forward. - Warn when the PKGBUILD has no
# Maintainer:line. - Audit the PKGBUILD:
pkgver()with the wrong strategy and mixed checksums block the update, and patches and anepochother than 0 warn, see Supported packages. - Set
pkgverwithsedandpkgrelto 1, or to thepkgrelof the AUR when the AUR has the version already, and the line ofupstream.asset_var, see Values from release asset names. Whenpkgverandpkgrelof the AUR hold these values already, read as bash reads them, the script writescurrentandcurrent_assetand exits with code 2. A dry run writes neither. - Check every
httpandhttpssource URL, whatever its checksum. Then runupdpkgsumsandmakepkg --verifysource --skippgpcheck, unless a checksum holds aSKIPthat makepkg does not write itself, see Packages with VCS checksums. Any failure stops the update. - Run
namcapwhen it is installed. Its errors stop the update, and its warnings are printed. - Regenerate
.SRCINFOwithmakepkg --printsrcinfo. - Check
PKGBUILDand.SRCINFOagainst the clone, as steps 4 and 5 of publish do. A refused file stops the update. - With
--dry-run, print the diff of the PKGBUILD and stop. - Commit as
<new-version> release from <strategy>, or<new-version>-<pkgrel> release from <strategy>for a rebuild, authored byGIT_AUTHOR_NAMEandGIT_AUTHOR_EMAIL, by defaultaurtomatorandaurtomator@users.noreply.github.com. WithGPG_KEY_ID, sign the commit, and push it unsigned when signing fails. - Push, with up to 3 attempts 5 seconds apart.
- Write
current,current_assetandlast_updatedto the package YAML.
AURTOMATOR_CLONE_DELAY and AURTOMATOR_RETRY_DELAY change the 2 and the 5 seconds.
Prepare and publish
Section titled “Prepare and publish”A PKGBUILD is a bash script, and steps 5 and 7 to 9 run it. Whoever can push to the AUR repository of a package, a co-maintainer for example, runs code there. The workflow splits the update so that this code never runs where the SSH key, the GPG key or a write token is: prepare runs it in a job of its own for each package, verify checks the checksums against the sources, and publish pushes files that neither job can change on the way.
Prepare, update-pkg.sh --prepare <dir>, holds no secrets:
- Clone
https://aur.archlinux.org/<package-name>.gitanonymously. - Run steps 3 to 9. With
--arch-out, the update also changes thearch=(...)line, see Versions without some arches. - Write
PKGBUILD,.SRCINFOand the commit id ofHEADasbaseto<dir>/<package-name>/. Nothing is committed. Exit code 2 means the AUR has the version already.
Verify, verify-pkg.sh <package-name> <version> <dir>/<package-name>, holds no secrets and never runs the PKGBUILD or makepkg:
- The prepared directory passes step 1 of publish.
- Clone anonymously with
--no-checkout, and exit with code 3 whenHEADis notbase: the AUR moved after the prepare. The files ofHEADare written out withgit ls-treeandgit cat-file, so no link, attribute or filter of the repository applies. Prepared files equal to these end the verify with exit code 0. - At the version of the AUR, the prepared files must be those of the AUR. Otherwise they pass steps 4 and 5 of publish with
<version>and the asset value of--asset, before anything is downloaded. - Each checksum array of the prepared
PKGBUILDholds the values of its key in the prepared.SRCINFO. - Every checksum other than
SKIPmatches its source, computed as makepkg computes it. A file of the AUR repository with the name of the source comes first. A remote source is downloaded overhttpsalone, redirects included, and a download stops past 600 MiB or below 100 KiB/s for 60 seconds; the downloads of one package share 1 GiB. A git source at#tag=or a full#commit=is fetched alone overhttpswith the same limits, and its checksum is that ofgit archive --format tar, as makepkg computes it. A checksum of a download overhttporftp, or of another VCS, cannot be checked and stops the verify. - Any mismatch stops the verify with exit code 1.
Publish, publish-pkg.sh <package-name> <version> <dir>/<package-name>, holds the keys and never runs the PKGBUILD or makepkg:
- The prepared directory is no symlink,
PKGBUILD,.SRCINFOandbaseare regular files, andbaseis a commit id. - Clone over SSH with
--no-checkoutand write the AUR copy as verify does. WhenHEADis notbase, exit with code 3. - At the version and asset value of the AUR, the prepared files must be those of the AUR: the publish sets
currentand exits with code 2. Otherwise the preparedpkgvermust be<version>. With--arch-out, an update that changesarch=(...)at the version of the AUR goes on to step 4, see Versions without some arches. - The prepared
PKGBUILDmay differ from the AUR copy only inpkgver=, which is<version>; inpkgrel=, which is1, or that of the AUR at its own version, or as Values from release asset names sets it; in the line ofupstream.asset_var; and in the values of the checksum arrays. The arrays keep their names, lengths andSKIPpositions and hold quoted hex checksums orSKIP, in their places or in one block at the place of the first, asupdpkgsumswrites them. A comment or an empty line inside an array must be one the AUR copy has, sinceupdpkgsumswrites none, and a backslash on the closing line stops the publish, since bash joins the next line to the assignment. - The prepared
.SRCINFOhas as many lines as the AUR copy, empty lines at the end left out, and each line follows from the AUR copy:- A
sourceline is the AUR line with the old version replaced by<version>. A source that isSKIPeverywhere may also change the digits of its saved name, the part before::, asneovim-20261014.tar.gzbecomesneovim-20261016.tar.gz. - Any other line whose value the text of the AUR
PKGBUILDholds, outside itspkgver=,pkgrel=, asset and checksum lines and its comment lines, stays as it is, asGPL-2.0does at version2.0. Any other line takes the new version, asprovides = demo=2.1does fromprovides=("demo=${pkgver}"), and the version with the AURpkgrelafter a dash may take the newpkgrelas well, asdepends = demo-common=2.1-1does fromdepends=("$pkgbase-common=$pkgver-$pkgrel"). - A replacement also covers the forms a PKGBUILD often derives from
pkgver: dots and plus signs as underscores (1_86_0,28_21of28+21), the part before the first+(0.13.0of0.13.0+dev+1853+g6edb38ca98), the version without its last component while it keeps a dot (6.19of6.19.0), the dash forms ofpkgver_dashand the upstream version ofpkgver_format. A form counts only where it does not continue a number, and each part of a line is replaced once. Any other form, or a version replaced in one place and kept in another, stops the publish. - When
pkgverchanges, at least one source URL or checksum changes for each architecture ofpkgbasewhere a download has a real checksum or a VCS source is pinned. A package of a split package witharch=(any)builds on each of these architectures and needs no change of its own. A download saved under a new name with the URL and the checksum of the old one is refused, since it holds the old file, see Sources that do not follow pkgver.
- A
- Any other difference, and a NUL byte in either file, stops the publish with exit code 1. The two files then enter the index of the clone byte for byte, through
git hash-object --no-filters, becausegit addwould pass them through the attributes of the AUR repository, andworking-tree-encoding=UTF-7there turns+AAo-in a comment into a new line. Steps 12 to 14 follow.
The AUR serves the description, the dependencies and the licenses of a package from .SRCINFO, and AUR helpers such as yay parse it. Code in prepare writes the .SRCINFO of its package, so step 5 derives every line from the text of the PKGBUILD, which verify and publish read without running it. In three cases that text does not tell how makepkg writes a line, and a correct update stops, see Lines the check cannot read from the PKGBUILD.
check-all.sh --prepare <dir> runs no strategy. It takes the versions from the statuses of the check run, new_version, available_downgrade, new_build and arch_back, with the asset values and arch lines of that run, and applies the rules of downgrades, version jumps, alerts and the cooldown again. A failed preparation becomes update_failed. --verify <dir> runs verify-pkg.sh for every prepared package with the same versions, removes an update that fails, and starts no package after 20 minutes, AURTOMATOR_VERIFY_BUDGET, so its job ends within 30. Its loop starts at another package each hour, so slow sources cannot hold back the same packages in every run. --publish <dir> takes the same statuses again, contacts no upstream host while the keys are in place, and publishes each prepared update. Exit code 3 of verify or publish leaves the package to the next run, which prepares it again. A run prepares at most 256 packages and leaves the rest for a later run.