[Feature] Add GitHub Action Workflow for Arch Linux AUR Package publishing #33

Merged
dearsky merged 11 commits from refs/pull/33/head into main 2026-04-09 22:22:39 +08:00
dearsky commented 2026-04-04 06:26:05 +08:00 (Migrated from gitea.proxy.dearsky.top)

Hi @razvandimescu ! I came across your post about Numa on Hacker News yesterday, and love the concept of this project.

Since I'm an Arch Linux user myself, I thought I'd write up a quick GitHub Actions workflow to publish Numa as an AUR package anytime the main branch updates, so that my system will auto-update anytime a new release is made.

Feel free to disregard/close this PR if it doesn't fit your needs. Otherwise, changes listed below!

Note: since I haven't created the AUR account/package myself, there's a chance there still might be a bug or two in this PR (especially as this is my first time attempting to create an AUR package 😅) . We can diagnose/solve together after you've created the AUR account (assuming you want this merge this PR, of course!).

Overview

  • This PR adds a GitHub Actions workflow to publish an AUR (Arch User Repository) package anytime the main branch is updated
  • This allows Arch Linux users to easily install Numa, and auto-update it anytime a new release is made (example package manager command: yay numa-git)

Changes

  • ./PKGBUILD: PKGBUILD is essentially a Bash script containing the build information required by Arch Linux packages.

  • .github/workflows/publish-aur.yml: a GitHub Actions workflow to build and publish the AUR package anytime this repo's main branch is updated.

  • README.md: added a one-liner install command for Arch Linux users.

TODO

To enable the AUR package publishing, you will personally need to setup an AUR account (if you don't have one already) to publish the package, and add some GitHub Secrets to this repo:

1. Create an AUR Account

2. Generate a Dedicated SSH Key for GitHub Actions

Open your terminal and generate a new key pair specifically for this GitHub Action (do not use your personal key):

ssh-keygen -t ed25519 -C "github-actions-numa-aur" -f ${HOME}/.ssh/aur_key
  • The private key is aur_key; you will need it for GitHub
  • The public key is aur_key.pub

3. Upload Public Key to AUR

  1. Log in to the AUR website.
  2. Go to My Account (top right).
  3. Paste the contents of ${HOME}/.ssh/aur_key.pub into the SSH Public Key field and save.

4. Create the AUR Repository

AUR "creates" a package automatically the first time you do a git push to its URL. You can do this once manually from your machine to "claim" the AUR package name:

# Clone this Pull Request
git clone https://github.com/CaseyLabs/numa-fork.git
cd numa-fork
git checkout feat/add-arch-linux-support

# Clone/create the AUR repo (`numa-git`)
cd ..
GIT_SSH_COMMAND="ssh -i ~/.ssh/aur_key" git clone ssh://aur@aur.archlinux.org/numa-git.git
cd numa-git

# Copy the PKGBUILD from this PR into this folder
cp ../numa-fork/PKGBUILD .

# Generate the .SRCINFO file (required for AUR)
docker run --rm -v "$(pwd):/pkg" archlinux:latest /bin/bash -c "
# Update and install minimal tools (binutils/git/sudo)
pacman -Syu --noconfirm --needed binutils git sudo && \

# Create a non-root user (makepkg refuses to run as root)
useradd -m builduser && \
chown -R builduser:builduser /pkg && \

# Mark the directory as safe for git (needed for the pkgver() function)
git config --global --add safe.directory '*' && \

# Run the metadata generator as the non-root user
# Note: we must fetch the source (`makepkg -od`) so that pkgver() can calculate the version
cd /pkg && sudo -u builduser makepkg -od && sudo -u builduser makepkg --printsrcinfo > .SRCINFO
"

# Commit and push
git add PKGBUILD .SRCINFO
git commit -m "Initial Arch Linux AUR package support"
git push origin master

5. Configure GitHub Secrets

In your GitHub repository, go to Settings > Secrets and variables > Actions and add the following Repository Secrets:

Secret Name Value
AUR_SSH_PRIVATE_KEY Paste the entire content of the aur_key file
AUR_PACKAGE_NAME numa-git
AUR_USERNAME Your AUR username
AUR_EMAIL Your AUR account email

Once these secrets are set, the workflow will automatically handle all future updates!

6. Test & Merge this Pull Request

Once this pull request is merged, a new Arch Linux AUR package will be published anytime you make a new merge to the main branch... meaning end-users like myself can auto-update Numa whenever a new release is created!

Hi @razvandimescu ! I came across your post about Numa on Hacker News yesterday, and love the concept of this project. Since I'm an Arch Linux user myself, I thought I'd write up a quick GitHub Actions workflow to publish Numa as an `AUR` package anytime the `main` branch updates, so that my system will auto-update anytime a new release is made. Feel free to disregard/close this PR if it doesn't fit your needs. Otherwise, changes listed below! **Note:** since I haven't created the AUR account/package myself, there's a chance there still might be a bug or two in this PR (especially as this is my first time attempting to create an AUR package 😅) . We can diagnose/solve together after you've created the AUR account (assuming you want this merge this PR, of course!). ## Overview - This PR adds a GitHub Actions workflow to publish an `AUR` (Arch User Repository) package anytime the `main` branch is updated - This allows Arch Linux users to easily install Numa, and auto-update it anytime a new release is made (example package manager command: `yay numa-git`) ## Changes - `./PKGBUILD`: PKGBUILD is essentially a Bash script containing the build information required by Arch Linux packages. - `.github/workflows/publish-aur.yml`: a GitHub Actions workflow to build and publish the AUR package anytime this repo's `main` branch is updated. - `README.md`: added a one-liner install command for Arch Linux users. ## TODO To enable the AUR package publishing, you will personally need to setup an AUR account (if you don't have one already) to publish the package, and add some GitHub Secrets to this repo: ### 1. Create an AUR Account - If you don't have one, register at [aur.archlinux.org/register](https://aur.archlinux.org/register/) ### 2. Generate a Dedicated SSH Key for GitHub Actions Open your terminal and generate a new key pair specifically for this GitHub Action (do not use your personal key): ```bash ssh-keygen -t ed25519 -C "github-actions-numa-aur" -f ${HOME}/.ssh/aur_key ``` - The private key is `aur_key`; you will need it for GitHub - The public key is `aur_key.pub` ### 3. Upload Public Key to AUR 1. Log in to the [AUR website](https://aur.archlinux.org/). 2. Go to **My Account** (top right). 3. Paste the contents of `${HOME}/.ssh/aur_key.pub` into the **SSH Public Key** field and save. #### 4. Create the AUR Repository AUR "creates" a package automatically the first time you do a git push to its URL. You can do this once manually from your machine to "claim" the AUR package name: ```bash # Clone this Pull Request git clone https://github.com/CaseyLabs/numa-fork.git cd numa-fork git checkout feat/add-arch-linux-support # Clone/create the AUR repo (`numa-git`) cd .. GIT_SSH_COMMAND="ssh -i ~/.ssh/aur_key" git clone ssh://aur@aur.archlinux.org/numa-git.git cd numa-git # Copy the PKGBUILD from this PR into this folder cp ../numa-fork/PKGBUILD . # Generate the .SRCINFO file (required for AUR) docker run --rm -v "$(pwd):/pkg" archlinux:latest /bin/bash -c " # Update and install minimal tools (binutils/git/sudo) pacman -Syu --noconfirm --needed binutils git sudo && \ # Create a non-root user (makepkg refuses to run as root) useradd -m builduser && \ chown -R builduser:builduser /pkg && \ # Mark the directory as safe for git (needed for the pkgver() function) git config --global --add safe.directory '*' && \ # Run the metadata generator as the non-root user # Note: we must fetch the source (`makepkg -od`) so that pkgver() can calculate the version cd /pkg && sudo -u builduser makepkg -od && sudo -u builduser makepkg --printsrcinfo > .SRCINFO " # Commit and push git add PKGBUILD .SRCINFO git commit -m "Initial Arch Linux AUR package support" git push origin master ``` #### 5. Configure GitHub Secrets In your GitHub repository, go to **Settings > Secrets and variables > Actions** and add the following **Repository Secrets**: | Secret Name | Value | | :--- | :--- | | `AUR_SSH_PRIVATE_KEY` | Paste the entire content of the `aur_key` file | | `AUR_PACKAGE_NAME` | `numa-git` | | `AUR_USERNAME` | Your AUR username | | `AUR_EMAIL` | Your AUR account email | Once these secrets are set, the workflow will automatically handle all future updates! #### 6. Test & Merge this Pull Request Once this pull request is merged, a new Arch Linux AUR package will be published anytime you make a new merge to the `main` branch... meaning end-users like myself can auto-update Numa whenever a new release is created!
dearsky commented 2026-04-09 00:35:25 +08:00 (Migrated from gitea.proxy.dearsky.top)

Hi @CaseyLabs — apologies for the slow response, and thank you for the contribution.

Your PR catalyzed an upstream fix. Reviewing your prepare() patches, I noticed numa was hardcoding /usr/local/var/numa on all Unix platforms instead of the FHS-correct /var/lib/numa on Linux. Shipped that fix in #43 (now in v0.10.1) — numa is now FHS-compliant on Linux, so PKGBUILD path patching is no longer needed at all. Your contribution had meaningful upstream impact before we even got to the AUR work.

I just pushed three small fixes to your branch:

  1. Simplified prepare() — dropped the sed patches now that #43 makes them unnecessary.
  2. Fixed package() sed for the systemd unit — your sed targeted ExecStart=/usr/local/bin/numa but numa.service actually uses {{exe_path}} as a placeholder (substituted by numa install at runtime via replace_exe_path()). The fixed sed is sed 's|{{exe_path}}|/usr/bin/numa /etc/numa.toml|g' so the AUR-installed unit gets a real ExecStart path that systemd can actually start.
  3. Fixed the broken docker/setup-qemu-action SHA pin — the pinned SHA 6882732593b27c7f95a044d559b586a46371a68e doesn't exist in upstream docker/setup-qemu-action. The verified v3.0.0 SHA is 68827325e0b33c7199eb31dd4e31fbe9023e06e3. Without this fix, the aarch64 validate job would fail to load the action at workflow start time.

Plus a small cosmetic refresh of the pkgver placeholder in PKGBUILD and .SRCINFO (was 0.9.1.r0.g1234abc from before v0.10.0; now 0.10.1.r0.g0000000 to reflect the current era — auto-overridden by pkgver() on each build either way).

Once you've had a chance to look these over, happy to merge the PR. Then I'll claim numa-git on AUR and the workflow takes over for future commits.

Genuinely thank you — not just for the code, but for being the catalyst on the FHS fix and the AUR conversation overall.

Hi @CaseyLabs — apologies for the slow response, and thank you for the contribution. **Your PR catalyzed an upstream fix.** Reviewing your `prepare()` patches, I noticed numa was hardcoding `/usr/local/var/numa` on all Unix platforms instead of the FHS-correct `/var/lib/numa` on Linux. Shipped that fix in #43 (now in v0.10.1) — numa is now FHS-compliant on Linux, so PKGBUILD path patching is no longer needed at all. Your contribution had meaningful upstream impact before we even got to the AUR work. I just pushed three small fixes to your branch: 1. **Simplified `prepare()`** — dropped the `sed` patches now that #43 makes them unnecessary. 2. **Fixed `package()` sed for the systemd unit** — your sed targeted `ExecStart=/usr/local/bin/numa` but `numa.service` actually uses `{{exe_path}}` as a placeholder (substituted by `numa install` at runtime via `replace_exe_path()`). The fixed sed is `sed 's|{{exe_path}}|/usr/bin/numa /etc/numa.toml|g'` so the AUR-installed unit gets a real `ExecStart` path that systemd can actually start. 3. **Fixed the broken `docker/setup-qemu-action` SHA pin** — the pinned SHA `6882732593b27c7f95a044d559b586a46371a68e` doesn't exist in upstream `docker/setup-qemu-action`. The verified v3.0.0 SHA is `68827325e0b33c7199eb31dd4e31fbe9023e06e3`. Without this fix, the `aarch64` validate job would fail to load the action at workflow start time. Plus a small cosmetic refresh of the `pkgver` placeholder in PKGBUILD and `.SRCINFO` (was `0.9.1.r0.g1234abc` from before v0.10.0; now `0.10.1.r0.g0000000` to reflect the current era — auto-overridden by `pkgver()` on each build either way). Once you've had a chance to look these over, happy to merge the PR. Then I'll claim `numa-git` on AUR and the workflow takes over for future commits. Genuinely thank you — not just for the code, but for being the catalyst on the FHS fix and the AUR conversation overall.
dearsky commented 2026-04-09 05:11:08 +08:00 (Migrated from gitea.proxy.dearsky.top)

Hey @razvandimescu - that's awesome this inspired the upstream fix, and it's been fun on my end learning how AUR packages are made! I've pushed a few changes to my branch, and I think we may be all set to go now.

New changes:

  • Turns out Arch Linux only officially supports x86_64 architectures (I wasn't aware of this and assumed Arch supported ARM64 by default 🤦), so I've removed the aarch64 from the AUR build process

  • Fixed the following Arch build issues: install rust directly, fetch sources before cargo audit, and run
    the audit inside the fetched repo, disabled makepkg LTO, and marked /etc/numa.toml as a backup file.

  • Updated the AUR GitHub Actions workflows to use actions/checkout v6.0.2

  • Added /build-dir to .gitignore for local AUR test runs.

Validation:

Note:

  • cargo audit still reports rustls-pemfile 2.2.0 as unmaintained (RUSTSEC-2025-0134), but that is currently a warning, not a failing condition. I may experiment with setting up Dependabot in a separate pull request.
Hey @razvandimescu - that's awesome this inspired the upstream fix, and it's been fun on my end learning how AUR packages are made! I've pushed a few changes to my branch, and I _think_ we may be all set to go now. **New changes:** - Turns out Arch Linux only officially supports x86_64 architectures (I wasn't aware of this and assumed Arch supported ARM64 by default 🤦), so I've removed the aarch64 from the AUR build process - Fixed the following Arch build issues: install rust directly, fetch sources before cargo audit, and run the audit inside the fetched repo, disabled makepkg LTO, and marked /etc/numa.toml as a backup file. - Updated the AUR GitHub Actions workflows to use `actions/checkout v6.0.2` - Added `/build-dir` to `.gitignore` for local AUR test runs. **Validation:** - https://github.com/CaseyLabs/numa-fork/actions/runs/24158273996/job/70502830887 **Note:** - cargo audit still reports `rustls-pemfile 2.2.0` as unmaintained (RUSTSEC-2025-0134), but that is currently a warning, not a failing condition. I may experiment with setting up Dependabot in a separate pull request.
dearsky commented 2026-04-09 18:40:29 +08:00 (Migrated from gitea.proxy.dearsky.top)

Hey @CaseyLabs - one more small fix I pushed to your branch.

The AUR SSH known_hosts fingerprint was truncated (52 chars of base64 vs the 71 expected for an ed25519 wire-format key), so it wouldn't have matched and the publish job would have failed at the git clone ssh://aur@... step. Verified the correct key via ssh-keyscan aur.archlinux.org and updated it:

aur.archlinux.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEuBKrPzbawxA/k2g6NcyV5jmqwJ2s+zpgZGZ7tpLIcN

Hey @CaseyLabs - one more small fix I pushed to your branch. The AUR SSH known_hosts fingerprint was truncated (52 chars of base64 vs the 71 expected for an ed25519 wire-format key), so it wouldn't have matched and the publish job would have failed at the git clone ssh://aur@... step. Verified the correct key via ssh-keyscan aur.archlinux.org and updated it: aur.archlinux.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEuBKrPzbawxA/k2g6NcyV5jmqwJ2s+zpgZGZ7tpLIcN
dearsky commented 2026-04-09 22:02:08 +08:00 (Migrated from gitea.proxy.dearsky.top)

@razvandimescu - looks good to me, I've synced up my branch with your change now!

@razvandimescu - looks good to me, I've synced up my branch with your change now!
dearsky commented 2026-04-10 00:12:08 +08:00 (Migrated from gitea.proxy.dearsky.top)

@razvandimescu - just noticed the builds on main for AUR are failing. Codex suggests the following:

Current issue: the earlier broken-quote bug was fixed, but the AUR publish job still fails because its Docker container runs makepkg -od, which triggers prepare() in PKGBUILD, and prepare() calls cargo fetch --locked even though that container does not install cargo or rust.

Potential fix:

  • Edit .github/workflows/publish-aur.yml
  • In the "Push to AUR" step, find this line:

pacman -Syu --noconfirm --needed binutils git sudo

  • Replace it with:

pacman -Syu --noconfirm --needed binutils git sudo rust

  • Commit and push the change
@razvandimescu - just noticed the builds on main for AUR are failing. Codex suggests the following: Current issue: the earlier broken-quote bug was fixed, but the AUR publish job still fails because its Docker container runs `makepkg -od`, which triggers `prepare()` in PKGBUILD, and `prepare()` calls `cargo fetch --locked` even though that container does not install cargo or rust. Potential fix: - Edit `.github/workflows/publish-aur.yml` - In the "Push to AUR" step, find this line: `pacman -Syu --noconfirm --needed binutils git sudo` - Replace it with: `pacman -Syu --noconfirm --needed binutils git sudo rust` - Commit and push the change
dearsky commented 2026-04-10 01:35:35 +08:00 (Migrated from gitea.proxy.dearsky.top)

@razvandimescu - we have lift-off!


> yay numa-git

Package (1)  New Version           Net Change
numa-git     0.10.1.r7.g17c8e70-1    9.73 MiB

Total Installed Size:  9.73 MiB

:: Proceed with installation? [Y/n]
(1/1) checking keys in keyring                     [-----------] 100%
(1/1) checking package integrity                   [-----------] 100%
(1/1) loading package files                        [-----------] 100%
(1/1) checking for file conflicts                  [-----------] 100%
:: Running pre-transaction hooks...
(1/2) Performing snapper pre snapshots for the following configurations...
==> root: 94
(2/2) Waiting for limine-snapper-sync to finish...
:: Processing package changes...
(1/1) installing numa-git                          [-----------] 100%
:: Running post-transaction hooks...
(1/3) Reloading system manager configuration...
(2/3) Arming ConditionNeedsUpdate...
(3/3) Performing snapper post snapshots for the following configurations...
==> root: 95

❯ sudo numa

╔═════════════════════════════════════════════════╗
║ NUMA  DNS that governs itself  v0.10.1         ║
╠═════════════════════════════════════════════════╣
║  DNS       127.0.0.1:5354                       ║
║  API       http://localhost:5380                ║
║  Dashboard http://localhost:5380                ║
║  Upstream  https://9.9.9.9/dns-query            ║
║  Zones     0 records                            ║
║  Cache     max 10000 entries                    ║
║  Blocking  1 lists                              ║
║  Proxy     http://:80 https://:443              ║
║            ⚠ proxy on 127.0.0.1 — .numa not LAN reachable║
║  Routing   1 conditional rules                  ║
╠─────────────────────────────────────────────────╣
║  Config    /home/user/.config/numa/numa.toml    ║
║  Data      /var/lib/numa                        ║
║  Services  /home/user/.config/numa/services.json║
╚═════════════════════════════════════════════════╝

[2026-04-09T17:32:41.095Z INFO  numa] numa listening on 127.0.0.1:5354, upstream https://9.9.9.9/dns-query, 0 zone records, cache max 10000, API on port 5380

Thanks for being so open to this pull request and process. I know it included a lot of extra work on your end, but a lot of Arch users will be happy to see this available as an AUR option now!

@razvandimescu - we have lift-off! ```shell > yay numa-git Package (1) New Version Net Change numa-git 0.10.1.r7.g17c8e70-1 9.73 MiB Total Installed Size: 9.73 MiB :: Proceed with installation? [Y/n] (1/1) checking keys in keyring [-----------] 100% (1/1) checking package integrity [-----------] 100% (1/1) loading package files [-----------] 100% (1/1) checking for file conflicts [-----------] 100% :: Running pre-transaction hooks... (1/2) Performing snapper pre snapshots for the following configurations... ==> root: 94 (2/2) Waiting for limine-snapper-sync to finish... :: Processing package changes... (1/1) installing numa-git [-----------] 100% :: Running post-transaction hooks... (1/3) Reloading system manager configuration... (2/3) Arming ConditionNeedsUpdate... (3/3) Performing snapper post snapshots for the following configurations... ==> root: 95 ❯ sudo numa ╔═════════════════════════════════════════════════╗ ║ NUMA DNS that governs itself v0.10.1 ║ ╠═════════════════════════════════════════════════╣ ║ DNS 127.0.0.1:5354 ║ ║ API http://localhost:5380 ║ ║ Dashboard http://localhost:5380 ║ ║ Upstream https://9.9.9.9/dns-query ║ ║ Zones 0 records ║ ║ Cache max 10000 entries ║ ║ Blocking 1 lists ║ ║ Proxy http://:80 https://:443 ║ ║ ⚠ proxy on 127.0.0.1 — .numa not LAN reachable║ ║ Routing 1 conditional rules ║ ╠─────────────────────────────────────────────────╣ ║ Config /home/user/.config/numa/numa.toml ║ ║ Data /var/lib/numa ║ ║ Services /home/user/.config/numa/services.json║ ╚═════════════════════════════════════════════════╝ [2026-04-09T17:32:41.095Z INFO numa] numa listening on 127.0.0.1:5354, upstream https://9.9.9.9/dns-query, 0 zone records, cache max 10000, API on port 5380 ``` Thanks for being so open to this pull request and process. I know it included a lot of extra work on your end, but a lot of Arch users will be happy to see this available as an AUR option now!
dearsky commented 2026-04-10 02:07:07 +08:00 (Migrated from gitea.proxy.dearsky.top)

Hey @CaseyLabs thanks so much for testing this, your banner actually caught a real bug.

numa's default isn't Quad9 - it tries to inherit your system DNS first and only falls back to Quad9 as a last resort.
It seems that on systems with NetworkManager + systemd-resolved, /etc/resolv.conf is a symlink to stub-resolv.conf containing just nameserver 127.0.0.53, and the real upstream lives inside systemd-resolved's per-link state.

numa was only parsing /etc/resolv.conf, filtering the stub, and falling through - so on most modern Linux desktops it silently landed on Quad9 instead of the user's actual router/ISP DNS.

I'm working on fixing this on #52

Hey @CaseyLabs thanks so much for testing this, your banner actually caught a real bug. numa's default isn't Quad9 - it tries to inherit your system DNS first and only falls back to Quad9 as a last resort. It seems that on systems with NetworkManager + systemd-resolved, /etc/resolv.conf is a symlink to stub-resolv.conf containing just nameserver 127.0.0.53, and the real upstream lives inside systemd-resolved's per-link state. numa was only parsing /etc/resolv.conf, filtering the stub, and falling through - so on most modern Linux desktops it silently landed on Quad9 instead of the user's actual router/ISP DNS. I'm working on fixing this on #52
Sign in to join this conversation.