Submitting a package to the AUR — full tutorial

Bouteiller < A2N > Alan
8 min readNov 24, 2023

--

You can find another story about submitting a tarball file into the AUR just here.

This tutorial is also available on YouTube.

You want to support me: applaud this story, check the video or leave a comment!

Today we are going to see how to publish a package to the AUR from a git source. And, btw, the tutorial works with any other version manager in theories.

In another story I have talked about how to make a submission to the AUR with a tarball file, the main difference between the two methods are how we handle the source and how we validate them.

For this tutorial I’m going to use my blurredwallpaper project, so mind to update the version, source, name and so on in function of your project.

Some prerequisite

For a git source we are going to use a gpg key when, for a tarball, we can just use a checksum.
This is important because I sign my commit and my tag with a gpg key, and like so we can tell our source to get the tag in question and check if the gpg signature is valid.

For signing your commit, you need to have a gpg key. You can create one with gpg or gpg2. This is pretty simple, we can do that with the following command:

gpg2 --full-generate-key

Then you have to tell git that you want to sign your commit and your tag and for that we need to have the id of the key.
For that, you just have to use:

gpg2 --list-secret-keys --keyid-format=long

The id is this number: 3AA5C34371567BD2 just at the sec line.

$ gpg2 --list-secret-keys --keyid-format=long
/Users/hubot/.gnupg/secring.gpg
- - - - - - - - - - - - - - - - - -
sec 4096R/3AA5C34371567BD2 2016–03–10 [expires: 2017–03–10]
uid Hubot <hubot@example.com>
ssb 4096R/4BB6D45482678BE3 2016–03–10

Next you have to execute this commands, the first one tells to git to use the key previously created and the second tell to git to actually sign your commit:

git config --global user.signingkey 3AA5C34371567BD2
git config --global commit.gpgsign true

And for a tag it is less automated, you need to add the -s flag when you create a tag, keep in mind the command we are going to use it very soon:

git tag -s MYTAG

Initialization

First, we are going to create a new directory and init our git repository:

mkdir mypackage
cd mypackage
git init

And now we can go for the real deal: the PKGBUILD file!

We can copy the prototype file from this arch wiki page: https://wiki.archlinux.org/title/Arch_package_guidelines and delete all the keys we don’t need and update the maintainer field:

# Maintainer: Your Name <youremail@domain.com>
pkgname="mypkgname-git"
pkgver=1.0.0
pkgrel=1
pkgdesc=""
arch=("any")
url=""
license=('GPL')
depends=()
makedepends=()
optdepends=()
source=()
md5sums=("SKIP")

pkgver() {}

package() {}

Ok! We have the base of our file.

So, some important things here:
- the pkgver key must be the same as the version number of your project
- because we are going to use a git source, we have to add -git at the end of the package name in pkgname
- the pkgver() function is use with git tag to update the version of our package automatically if needed
- because we are going to use gpg to validate the source, we can ”SKIP” the md5sums check

Adding the source

Like I said at the beginning, we are going to use a git source and not a tarball. And because it’s a git source, we need to have a way to focus a particular version of our code. And for that, git gives us access to tags.

So the first step is to create a tag, signed by gpg, representing the commit of your current project version. And obviously you need to do that in the project repository, not on the PKGBUILD repository. For me, it’s the last commit so I just have to go on my main branch and do :

git tag -s v2.2.0

Ok, now we have a tag signed by gpg!

Next, we need to add a new variable into our PKGBUILD file _tag. The _ is part of the package etiquette defined in the arch wiki, so it’s mandatory.

The _tag variables may contain the tag we just created before, but we can’t put its row value (v2.2.0) because if, for some reason, we push force another commit on the tag, the tag remains the same but the commit change. So for avoiding that we have to use the hash of the tag.
For that, we just have to go on the main branch of our project and get the hash of the last tag via git rev-parse v2.2.0 that give us the hash: 123456789123456789.

Now that we have the variable _tag populated with our hash, we can use that to set the right url for the source key:

url="https://github.com/bouteillerAlan/blurredwallpaper"
source=("git+${url}.git#tag=${_tag}?signed")

Validating the source

Ok now we need to validate the source via the tag signed by gpg.
The process is very simple, the first step is to add our gpg key into a gpg server. This is mandatory because we need to have our key available on the net, like so when user installed our package the process can check the key automatically.

The easiest way of doing that is to add our key to a public server, for example: https://keyserver.ubuntu.com.

You can do it automatically via the “Publish on server…” button kleopatra or manually directly via the website.

And next we just have to add the id of the key to a new key in our PKGBUILD file :

validpgpkeys=(
6A2ECC8A396F8A943A109A1E0F11C2A6BF79111E
)

Updating the pkgver

With the use of a git source, we can update the `pkgver` automatically via the following function:

_sourceName="blurredwallpaper"
pkgver() {
cd "${_sourceName}"
git describe --tags | sed 's/^v//'
}

Here I have created a new variable _sourceName populated with the name of my repository.
Then we cd in the clone of our repository and get the last tag. The sed option is just here for deleting the v at the start of our tag.

Ok, now so far we have the following file:

# Maintainer: Your Name <youremail@domain.com>
_tag=123456789123456789
_sourceName="blurredwallpaper"

pkgname="kdeplasma-blurredwallpaper-git"
pkgver=2.2.0
pkgrel=1
pkgdesc="KDE plasma wallpaper plugin that blur the wallpaper when a window is active"
arch=("any")
url="https://github.com/bouteillerAlan/blurredwallpaper"
license=("GPL3")
depends=()
makedepends=()
optdepends=()
source=("git+${url}.git#tag=${_tag}?signed")
md5sums=("SKIP")
validpgpkeys=(6A2ECC8A396F8A943A109A1E0F11C2A6BF79111E)

pkgver() {
cd "${_sourceName}"
git describe --tags | sed 's/^v//'
}

package() {}

The (mostly) last step : packaging

For finishing up our PKGBUILD file, we have to add the dependencies and set the mandatory package() function.

The dependencies are linked to your project so you have to check that your dependencies are correct. But we have some key points here :
- the depends option is for your project dependencies, in my project I don’t have any dependencies
- the optdepends option if you have optional dependencies, same for me no optional dependencies in my project
- the makedepends option where you have to add git because we create a package sourced from git (and use git in the pkgver() function for example)

Next, we have to implement the mandatory package() function:

# we cd into the project folder
cd "${_sourceName}"
# place the license file into the right directory
install -Dm 644 LICENSE -t "${pkgdir}"/usr/share/licenses/"${pkgname}"/
# we create the plasmoid directory
mkdir -p "${pkgdir}/usr/share/plasma/wallpapers/${_plasmoidName}"

# and we place our project into the right directory
install -Dm 644 metadata.json -t "${pkgdir}"/usr/share/plasma/wallpapers/"${_plasmoidName}"/
find "contents" -type f -exec install -Dm 644 "{}" "${pkgdir}/usr/share/plasma/wallpapers/${_plasmoidName}/{}" \;

The first two commands are very simple, the install command is recommended in place of the cp command because install can also handle permissions.

The last command use find for listing all the directories and files, and next use install to move all that into the right directory.

Also we use another variable _plasmoidName that has been populated with the name of my plasmoid a2n.blur.

Ok so far our file looks like this :

# Maintainer: Bouteiller a2n Alan <a2n.dev@pm.me>

_tag=123456789123456789
_sourceName="blurredwallpaper"
_plasmoidName="a2n.blur"

pkgname="kdeplasma-blurredwallpaper-git"
pkgver=2.2.0
pkgrel=1
pkgdesc="KDE plasma wallpaper plugin that blur the wallpaper when a window is active"
arch=("any")
url="https://github.com/bouteillerAlan/blurredwallpaper"
license=("GPL3")
depends=()
makedepends=(git)
optdepends=()
source=("git+${url}.git#tag=${_tag}?signed")
md5sums=("SKIP")
validpgpkeys=(6A2ECC8A396F8A943A109A1E0F11C2A6BF79111E)

pkgver() {
cd "${_sourceName}"
git describe --tags | sed 's/^v//'
}

package() {
cd "${_sourceName}"
install -Dm 644 LICENSE -t "${pkgdir}"/usr/share/licenses/"${pkgname}"/
mkdir -p "${pkgdir}/usr/share/plasma/wallpapers/${_plasmoidName}"
install -Dm 644 metadata.json -t "${pkgdir}"/usr/share/plasma/wallpapers/"${_plasmoidName}"/
find "contents" -type f -exec install -Dm 644 "{}" "${pkgdir}/usr/share/plasma/wallpapers/${_plasmoidName}/{}" \;
}

The real last step : quality check

Before submitting, we have to ensure that our package and code is bulletproof with “quality assurance step”.

The first one is very simple, just run the makepkg command in your working directory. If this command fails, recheck your code. For me, no problem with this step.

For validating this step, you can check for :
- a file named pkgname-pkgver.pkg.tar.zst in the folder (this package can be installed with the pacman -U command)
- a rule of thumbs is to check if this package contains all the file and dependencies you want with pacman -Qlp [package file] and pacman -Qip [package file] commands

For example, my result :

[a2n@a2n-eso dracut-numlock]$ pacman -Qlp kdeplasma-blurredwallpaper-git-2.2.0-1-any.pkg.tar.zst 
dracut-numlock /usr/
dracut-numlock /usr/share/
dracut-numlock /usr/lib/licenses/
...

After checking all that, we can use the namcap (is it pacman that’s upside down or nampac?) command to check the package sanity.

You can install it via the namcap package : https://archlinux.org/packages/extra/any/namcap/

This command check the PKGBUILD contents for common errors and package file hierarchy for unnecessary/misplaced files, then check if the depends options is well setup (in short, read the doc here).

So we have to run :

namcap PKGBUILD
namcap _<package file name>_.pkg.tar.zst

In my case, I have no error or warning :)

If you want to test that command, you can remove the git dependency and rerun the namcap PKGBUILD command.

Another step you want to do before submitting the package is checking if all the files and directories present under the pkg directory (created by the makepkg command) are ok. This directory represents the actual result the user is going to have.

Submitting the package

First you need to add an ssh key to your account right there : https://aur.archlinux.org/account/[your-username]/edit.

You have to add a new line for this key in your ssh config file :

Host aur.archlinux.org
IdentityFile ~/.ssh/aur
User aur

The IdentityFile should correspond to your private key.

Next, we have to add the remote repository to our existing project :

git remote add aur ssh://aur@aur.archlinux.org/kdeplasma-blurredwallpaper-git.git

and then :

git fetch aur

Note that the aur works only with main branch that has been called master.

Now we need to generate the .SRCINFO file, commit it and then push it to the new remote aur.
We can do that with the following command :

makepkg --printsrcinfo > .SRCINFO

And we can commit both of the file :

git add .SRCINFO PKGBUILD
git commit -am 'add pkgbuild and srcinfo'

You have to make sure that the last commit have both file in it. If it’s not the case, the push is rejected by the AUR repository.

Ok, you are at the end of this tutorial, you just need to push your package with the following command :

git push --set-upstream aur master

Checking if the submission is ok

For that, nothing special to do, you just have to check your AUR home page. if the package is well submitted, the package is shown on your list.

You can run an install, with yay for example, if you want to try your new package :

yay -S kdeplasma-blurredwallpaper-git

That’s all folks, thanks for reading :)

--

--