Commit Graph
118 Commits
Author SHA1 Message Date
alvinlolloandClaude Opus 5.5 b68623a782 docs: Document the zsh-autocomplete partial-load error and fixes
Upstream pin check / quickshell-pin (push) Successful in 20s
Tests / tests (push) Successful in 3m0s
Adds a Troubleshooting entry (symptom, cause, drop-or-keep fixes). The
keep path removes grml-zsh-config instead of setting
skip_global_compinit=1: grml's /etc/zsh/zshrc runs compinit
unconditionally and ignores that Debian/Ubuntu variable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 18:08:30 +11:00
alvinlolloandClaude Opus 5.5 88e73bbc22 docs: Sync AGENTS.md with CI lint, fish default, zshrc staging
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:41:39 +11:00
alvinlolloandClaude Opus 5.5 025082a92f fix(localrepo): Exact local package match, no .old on medium, rebuild on bump
- tests: match localrepo packages by exact name (foo no longer satisfied
  by foo-bar-*.pkg.tar.zst).
- update.sh: copy the db/files by name so repo-add's *.old backups stay
  off the medium.
- build-end4-deps.sh: rebuild a local PKGBUILD when it is newer than the
  built package (a quickshell _commit bump used to be skipped).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:41:38 +11:00
alvinlolloandClaude Opus 5.5 699ed6a935 fix(installer): Validate hostname, parse disk models, skip zram
- screen_hostname: reject names that break /etc/hostname and /etc/hosts.
- screen_disk: parse lsblk -P by regex so multi-word/empty MODELs show
  correctly, and never offer /dev/zram* (TYPE=disk) as a target.
- packages: add python-distro, the undeclared runtime dep of the shipped
  ssh-import-id (it always crashed and fell back to curl).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:41:38 +11:00
alvinlolloandClaude Opus 5.5 e63f9cb14f fix(iso): Ship an archiso preset for linux-cachyos, the kernel we boot
linux.preset targeted the 'linux' package, which is not on the ISO, so
linux-cachyos generated its own default+fallback preset and the squashfs
carried an unused fallback initramfs. No package owns the preset file
(mkinitcpio's hook only creates one if missing), so this cannot conflict.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:41:38 +11:00
alvinlolloandClaude Opus 5.5 c5c7ab9b8b fix(ci): Lint extensionless scripts, serialize tests, drop pinned URLs
- ShellCheck now also covers bash scripts without .sh (alvin-install,
  choose-mirror, livecd-sound), picked up by shebang.
- concurrency group: the job rewrites the runner's /etc/pacman.conf.
- Import the CachyOS key from the keyserver instead of pacman -U on
  pinned keyring/mirrorlist URLs that break once the mirror prunes them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:39:22 +11:00
alvinlolloandClaude Opus 5.5 03f0ca05e0 fix(build): Verify cachyos and chaotic-aur signatures at ISO build time
Both repos used SigLevel = Optional TrustAll, so unsigned or tampered
packages went straight into the ISO. Inherit Required DatabaseOptional
from [options] and have build-iso import + lsign both signing keys.

Also in build-iso: detach only loop devices backed by the work dir
(losetup -D hit every loop on the runner host) and drop the ?token=
download fallback that put the API token into access logs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:39:22 +11:00
alvinlolloandClaude Opus 5.5 5299b90bbc fix(skel): Keep script exec bits and ship a .zshrc for oh-my-zsh
- Replace the 644/755 chmod sweep (which also undid its own chmod 700)
  with go-w,a+rX so non-.sh executables keep +x.
- Install an oh-my-zsh .zshrc into /etc/skel after pacstrap. It is staged
  as /root/.zshrc-skel because grml-zsh-config owns /etc/skel/.zshrc and
  an airootfs copy would abort pacstrap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:38:11 +11:00
alvinlolloandClaude Opus 5.5 55b66a1373 fix(installer): Survive copytoram, keep ISO repos, default to fish
- install_pacstrap: fall back to the live system's pacman -Q when the
  medium's pkglist is gone (copytoram unmounts bootmnt), and die on an
  empty list instead of pacstrapping only the essentials.
- screen_disk: find the live medium via archisosearchuuid when bootmnt
  is unmounted, and hide whole-disk sources (empty PKNAME).
- install_cachyos_repo: put [cachyos] ahead of [core] like the ISO build
  and add [chaotic-aur], so chaotic packages keep updating.
- install_user: create the user with fish; the 'none' login manager now
  autostarts Hyprland via ~/.config/fish/conf.d/alvin-hyprland.fish.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:38:11 +11:00
alvinlolloandClaude Opus 5.5 504a568570 chore(localrepo): Stop tracking makepkg output and repo-add backups
build-end4-deps.sh builds in place, so pkg/, src/ and the VCS mirrors
under end4-pkgbuilds/ (incl. a built quickshell tree) ended up in git.
Ignore everything there except PKGBUILDs and hooks, plus *.old backups.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:38:00 +11:00
alvinlolloandClaude Opus 5.5 0ae2f036b7 fix(ci): Stop bash -e from killing the conflict check silently
Tests / tests (push) Successful in 3m29s
The `pacman -S` in the conflict check exits non-zero by design (a
conflict fails in prepare, a clean list fails at the disabled download),
and `OUT=$(...)` carries that status, so `bash -e` aborted the step
before the output was inspected: exit 1 with no message on every run.
Ignore the status and judge by the output, as intended.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 16:25:17 +11:00
alvinlolloandClaude Opus 5.5 0e57df4360 fix(ci): Make the package conflict check actually detect conflicts
Tests / tests (push) Failing after 2m53s
The step ran `pacman -Sp`, which skips conflict checking entirely: it
happily prints URLs for eternalterminal + eternalterminal-client and
exits 0. It also skipped every localrepo package, so the conflict fixed
in f06bfd1 could never have been caught here.

Now the check resolves against a throwaway config that adds [local-aur]
(localrepo/), with a fresh dbpath/root so runner-installed packages
don't mask or fake conflicts, and runs a real `pacman -S`. Conflicts and
broken deps fail in "prepare", before any download; XferCommand is set
to /usr/bin/false after the sync so a clean list stops at the download
instead of fetching the whole ISO. Package availability comes from one
`-Slq` instead of ~400 `-Si` calls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:50:35 +11:00
alvinlolloandClaude Opus 5.5 da26e88147 fix(localrepo): Drop stale packages so update.sh can't re-add them
f06bfd1 and a940d91 removed eternalterminal-client/-server,
illogical-impulse-quickshell-git, meshy-git and pacserve from
packages.x86_64, but their .pkg.tar.zst files stayed in localrepo/ and
in local-aur.db. update.sh appends every localrepo package name back to
the list, which would bring the eternalterminal conflict back, and CI
shipped the conflicting packages into the image's /opt/localrepo.

Remove the files and their repo DB entries, re-sort the vulkan-* lines
in packages.x86_64, and drop the names from README.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:39:06 +11:00
alvinlollo f06bfd1512 fix(ci): Remove conflicting packages
Tests / tests (push) Successful in 4m36s
iso-2026.10.08-r1
2026-10-08 21:44:54 +11:00
alvinlollo a940d91794 fix(ci): Fix end4 dependecies
Tests / tests (push) Successful in 4m35s
2026-10-08 20:53:54 +11:00
alvinlollo 9af4bc6c27 fix(tests): Fix yamlint compliance with whitespace
Tests / tests (push) Successful in 4m31s
2026-10-08 19:01:25 +11:00
alvinlollo 3c540f8bed fix(test): Fix yaml formatting
Tests / tests (push) Failing after 24s
2026-10-08 18:55:27 +11:00
alvinlollo 3f3bba05f3 fix(test): Fix formatting
Tests / tests (push) Failing after 25s
2026-10-08 18:53:51 +11:00
alvinlollo 01913f7682 feat(jobs): Output conflicting packages
Tests / tests (push) Failing after 2m24s
2026-10-08 18:46:47 +11:00
alvinlollo f9a2978517 Update MicroTeX submodule pointer
Tests / tests (push) Failing after 2m30s
2026-10-08 18:35:41 +11:00
alvinlollo 1e8a1e3282 fix(ci): Update Qt version to latest
Upstream pin check / quickshell-pin (push) Successful in 46s
Tests / tests (push) Failing after 2m54s
2026-10-08 18:19:34 +11:00
alvinlollo db83549996 feat(gum): Add further additions of gum to install script
Tests / tests (push) Successful in 2m29s
2026-10-08 14:48:20 +11:00
alvinlollo 59d82f06f5 feat(installer): sshd opt-in, gsettings replay, live-medium motd stamp
Tests / tests (push) Successful in 2m50s
- alvin-install: new sshd screen (default on) + install step. openssh is
  guaranteed into the pacstrap list when requested, and the final banner
  reports whether the enable actually succeeded (SSHD_APPLIED) instead of
  what was selected. The prompt warns that password login uses the same
  password as LUKS, and only mentions the GitHub key import when a
  username was given.
- alvin-install: replay the `gsettings set` commands end-4 logged during
  its setup run with a clean env and a throwaway session bus as the target
  user, then read each key back in a second session to confirm it persisted
  (gvariant_unescape normalizes both '...' and "..." GVariant output). The
  venv check now walks the uv bin/python symlink chain, re-rooting
  absolute hops under $TARGET, since that link dangles on the live medium.
- build: append the build stamp to the live /etc/motd (keeps the installed
  system's motd untouched) and drop alvin-install's install_motd step.
- docs: installer sections in README/AGENTS.md, sshd notes, corrected line
  counts.
2026-10-07 21:55:30 +11:00
alvinlollo 1bb6f8dddd ci: install archiso via private pacman config, not /etc/pacman.conf
Tests / tests (push) Successful in 4m8s
Writing stock core/extra over the host /etc/pacman.conf raced with the
tests workflow, which appends [cachyos]/[chaotic-aur] to the same file —
runs 132 and 133 ran concurrently on the runner, so either job could
corrupt the other's config mid-pacman.

Use 'pacman --config $(mktemp)' with stock core/extra instead: same
DNS-lookup reduction (only core/extra sync, no cachyos/chaotic), zero
writes to shared state. Verified on the runner: exit 0, only core/extra
synced, host /etc/pacman.conf mtime unchanged.
iso-2026.10.07-r1
2026-10-07 11:22:12 +11:00
alvinlollo 0fbec83573 ci: retry pacman syncs and reset host pacman.conf before build
Tests / tests (push) Successful in 5m7s
Run 131 failed at 'pacman -Syu archiso jq' because the gateway
(192.168.1.1) intermittently drops UDP/53: cachyos.db and chaotic-aur.db
lookups hit libalpm's 10s resolve timeout while core/extra survived on
resolved's cache.

- build-iso: reset the host /etc/pacman.conf to stock core/extra first
  (tests.yaml leaves [cachyos]/[chaotic-aur] behind, and mkarchiso reads
  the profile's pacman.conf anyway), pre-warm mirror hostnames in the
  resolver cache, then retry pacman -Syu 5x with backoff.
- tests: wrap all three pacman -Syu calls in the same retry loop.

DNS-side redundancy was added on the runner separately (networkd drop-in
adds 1.1.1.1/8.8.8.8 next to the gateway).
2026-10-07 11:14:28 +11:00
alvinlollo a6c99b72d0 fix(ci): ensure /dev/fd symlinks exist for mkinitcpio and procsub
Tests / tests (push) Successful in 2m33s
The chroot's /dev only gains fd/stdin/stdout/stderr symlinks at boot, and
container executors often lack them, which breaks mkinitcpio's preset step
(pipes through /dev/stdin) and bash process substitution
("/dev/fd/63: No such file or directory").

- build-iso workflow: create the links in the executor's /dev, then mount a
  fresh devtmpfs and create them there too so the chroot tree is covered
  whether the executor's /dev is devtmpfs or a plain tmpfs
- customize_airootfs.sh: self-heal the same links inside the chroot
2026-10-06 14:53:16 +11:00
alvinlollo c64c64dc97 feat(installer): ask GitHub username first in git screen
Tests / tests (push) Successful in 2m14s
screen_git now prompts GitHub username before git name/email, and the
screen description plus installation summary list SSH before git to
match the new prompt order. Behavior unchanged - prompts are
independent and all assignment sites are read after the screen returns.
2026-10-05 17:42:15 +11:00
alvinlollo 319333e400 fix(packages): rename syncthingtray-qt6, ship neofetch from localrepo
Tests / tests (push) Successful in 2m23s
CI package check failed on main (400/402):

- syncthingtray-qt6 no longer exists in the AUR (RPC returns nothing);
  the qt6 build is now the official 'syncthingtray' package in extra/
  cachyos - rename it in packages.x86_64 and drop the dead
  AUR_MISSING entry from build-end4-deps.sh
- neofetch left the distro repos (only chaotic-neofetch-git remains);
  build the AUR package locally (7.1.0-2, PGP-verified against Dylan
  Araps' key) and commit it to localrepo/ with a reindexed local-aur
  db so both the CI check (file glob) and pacstrap ([local-aur]) work
- un-indent the package lists in build-end4-deps.sh: CI accepts
  repo-less packages via 'grep -qxF <name>' (exact whole-line match),
  which could never match indented names

Verified locally with an exact replica of the CI check: 402/402.
2026-10-05 17:32:23 +11:00
alvinlollo bb6f64e977 feat(installer): build-stamp motd, LUKS mode A/B, TPM2, unl0kr, login managers
Tests / tests (push) Failing after 2m33s
- profiledef.sh stages airootfs/root/.iso-build-stamp (git/CI gated, falls
  back to 'commit unknown'); customize_airootfs.sh installs it as
  /etc/alvin-build-stamp; install_motd appends it to the target /etc/motd
- alvin-install: skippable git/GitHub screens with ssh-import-id import
  (yay build + python-distro, curl .keys fallback), LUKS Mode A (systemd
  sd-encrypt + rd.luks.name) vs Mode B (unl0kr + cryptdevice), TPM2
  enrollment via $PASSWORD with rd.luks.options activation, unl0kr
  build/verify with Mode-A fallback, login manager none/greetd/sddm/gdm
  (enable DM before disabling getty@tty1), autologin per DM (forced off
  when TPM enrolled), build-stamp motd; includes the existing
  GRUB_DISABLE_BOOTNEXT grub tweak
- review fixes: greetd autologin TOML quoting, .ssh chowned before
  ssh-import-id, builtin-aware initramfs module verification across all
  installed kernels, curl exit-code split (fetch failure vs no keys),
  plain Hyprland on every login path
- add curl to packages.x86_64; document stamp flow and installer in
  AGENTS.md/README.md
2026-10-05 16:26:12 +11:00
alvinlollo 3b3764573e fix(installer): resolve owner in one chroot call, log ydotool link errors
Tests / tests (push) Failing after 2m28s
Two low-severity review findings on 8501a60:

- owner="$(id -u):$(id -g)" as two substitutions only propagates the
  last status, so a lone id -u failure would build ':1000' and abort at
  the chown with "invalid owner" under the wrong line. Run both ids in
  a single arch-chroot sh -c chained with && and join with paste -sd:;
  pipefail makes any failure abort at the owner= line. Verified both
  paths: existing user yields 1000:1000, missing user trips the ERR
  trap before owner is used.
- the ydotool symlink mkdir/ln wrote stderr to the terminal while the
  failure warn pointed at $LOG, which never recorded it; redirect both
  into the log, matching the bluetooth block.
2026-10-02 17:18:40 +10:00
alvinlollo 8501a60165 fix(installer): chown target files by numeric id, not live-medium name
The end-4 step's chowns ran on the live medium, whose /etc/passwd has
no $USERNAME (the user exists only inside /mnt), so 'chown -R
alvin:alvin' failed with "invalid user" and the ERR trap aborted the
install at line 543. Resolve uid/gid once via arch-chroot id and chown
by number; the three remaining name-based chowns (fork/fish/hypr
restores) would have hit the same wall later.

Replace those three mid-function chowns with one catch-all over the
target home after the last root-side write: sed -i on the presets
rewrites through a temp file, which leaves them root-owned with no
chown after it.

systemctl --user enable ydotool.service could never work inside the
chroot (no /run/user/UID/bus exists before boot; it only ever warned
with "Failed to connect to user scope bus", so ydotool never
autostarted). Write the symlink enable would write:
~/.config/systemd/user/default.target.wants/ydotool.service ->
/usr/lib/systemd/user/ydotool.service.
2026-10-02 17:05:19 +10:00
alvinlollo 7c601ca53d ci: log HTTP status and response body on ISO upload failure
Tests / tests (push) Failing after 2m30s
`curl -f` swallowed Gitea's error response, so the 3-attempt upload
failure on the 6330 MiB ISO reported nothing diagnosable. Capture the
status code via -w, print up to 2 KB of the response body for both
HTTP-level and transport-level failures, and clear upload.json at the
start of each attempt so a stale body cannot be misreported.
2026-09-27 18:33:04 +10:00
alvinlollo f3bd10cf0f fix(iso): sweep ii-builder leftovers via NSpid before userdel
Tests / tests (push) Successful in 2m19s
end-4's ./setup sudo keepalive orphans a `sleep 60` child as ii-builder;
userdel then exits 8 and aborts the ISO build (CI exit 8).

Sweep uid-matching processes inside the build chroot before userdel,
mirroring shadow's user_busy_processes() checks (real/effective/saved
uid + root device/inode). Because arch-chroot mounts proc before
`unshare --fork --pid`, /proc entry numbers are outer-namespace pids:
signal the last NSpid field instead, require matching NSpid depth, and
surface kill errors instead of swallowing them. userdel keeps its stderr
and, on final failure, dumps the leftover process list before aborting.
2026-09-27 14:03:47 +10:00
alvinlollo 83ed87f6a9 feat(iso): build end-4 deps in-image, ship end4-pC as default shell
Tests / tests (push) Successful in 2m35s
- customize_airootfs.sh stages dots-hyprland at /opt, runs ./setup
  install-deps as a throwaway builder, harvests the built packages into
  /opt/localrepo so pacstrap resolves them offline
- image ships its own [local-aur] (file:///opt/localrepo); CI and
  localrepo/update.sh keep that copy in sync; .gitignore covers work/,
  out/ and airootfs/opt/localrepo/
- alvin-install runs ./setup install --skip-alldeps on the target
- clone pctrade/end4-pC into /etc/skel/.config/quickshell, patch qsConfig
  ii -> end4-pC in the staged variables.lua (guarded + idempotent), and
  restore the fork after setup rsync --delete's ~/.config/quickshell
- ship user presets in skel, point fish `q` alias at end4-pC
- AGENTS.md: document the fourth package source and new gotchas
2026-09-27 10:31:49 +10:00
alvinlollo 5ffd5d0d82 ci: pin SOURCE_DATE_EPOCH, assert ISO uuid metadata, verify uploads
Tests / tests (push) Canceled after 1m42s
- Export SOURCE_DATE_EPOCH before mkarchiso so label, volume UUID,
  file mtimes and ext4 hash seed trace to one timestamp.
- Post-build step: assert blkid UUID of the ISO matches every
  /boot/<uuid>.uuid stem and archisosearchuuid= reference inside
  shipped boot configs, and that no %ARCHISO% placeholder remains.
- After upload: re-hash local ISOs, size-check API assets, download
  each back from the internal origin (bypasses traefik/Anubis) with
  percent-encoded filenames (iso_name contains a space), compare
  SHA-256. Definitive corruption (missing/size/sha mismatch) deletes
  the release; transport/API errors fail without deleting.
2026-09-23 22:32:08 +10:00
alvinlollo 8484bddcf2 fix(installer): parse pkglist name field, skip unresolvable pkgs, keymap confirm
pacstrap failed at line 382 because pkglist lines from pacman -Q are
'name version' and were passed whole as pacman targets (~400 'target
not found'). Parse only the first field, pre-filter against pacman -Slq
so packages missing from the live repos (local-aur) are skipped with a
warning, and fall back to an unfiltered list if pacman -Syy fails.
Keymap screen now offers a US-layout confirm before the gum filter.
2026-09-23 22:32:01 +10:00
alvinlollo 0755091721 ci: add 3-try retry loop and timeouts for ISO release upload
Tests / tests (push) Successful in 2m17s
2026-09-22 22:06:33 +10:00
alvinlollo c71168371d fix(ci): upload plain ISO directly, skip zstd compression
Tests / tests (push) Successful in 2m22s
Compression was 5.3 GiB -> 5.2 GiB (98.6%) — negligible savings for
the extra build time. Upload the .iso directly as a release asset.
2026-09-21 19:56:07 +10:00
alvinlollo 117b5e97aa Add alvin-install TUI installer, fix NetworkManager boot
Tests / tests (push) Successful in 2m23s
- New gum-based installer script (alvin-install) with LUKS encryption,
  nmtui networking, disk selector, user/git config, and CachyOS repo setup
- Replace NetworkManager full unit file with symlink for consistency
- Add alvin-install reference to MOTD
- Add file_permissions entry in profiledef.sh
- Fix localrepo path case in pacman.conf
2026-09-20 22:22:20 +10:00
alvinlollo 8a88921913 fix: use linux-cachyos kernel in all boot entries
Tests / tests (push) Successful in 2m16s
Boot configs referenced stock vmlinuz-linux/initramfs-linux.img but
only linux-cachyos is installed. This caused boot to fall through
to memtest86+ since the kernel file was not found.
2026-09-20 17:02:20 +10:00
alvinlollo 9614192416 fix(ci): replace git LFS with release asset uploads
Tests / tests (push) Successful in 2m34s
The GITEA_TOKEN lacks 'lfs' scope, causing the LFS batch API to reject
uploads. Upload .zst files directly as release assets via the Gitea API
instead. This eliminates git-lfs, the separate releases repo, and all
LFS-related plumbing.
2026-09-20 13:24:37 +10:00
alvinlollo 2f1ac8d052 fix(ci): remove stderr suppression on push to diagnose LFS upload failure
Tests / tests (push) Successful in 2m21s
2026-09-20 10:24:51 +10:00
alvinlollo fa7eff8517 fix(ci): skip LFS smudge on releases repo clone
Tests / tests (push) Successful in 2m17s
2026-09-19 21:47:53 +10:00
alvinlollo 24f3f0f399 fix(ci): keep latest 2 releases instead of 3, clean up .releases-repo in always step
Tests / tests (push) Successful in 2m13s
2026-09-19 21:39:53 +10:00
alvinlollo ac59de33c8 fix(ci): move releases clone out of /tmp and free disk after LFS push
Tests / tests (push) Successful in 2m18s
2026-09-19 21:34:21 +10:00
alvinlollo da0855d341 Add --rm to remove source ISO
Tests / tests (push) Successful in 2m32s
2026-09-18 12:49:33 +10:00
alvinlollo 50d49bbe38 fix(ci): add PreTransaction hook to ensure /dev/stdin exists inside pacstrap chroot
Tests / tests (push) Successful in 2m31s
2026-09-17 15:58:16 +10:00
alvinlollo 1090e3c75b fix(ci): ensure /dev/stdin exists for mkinitcpio and remove stock linux kernel
Tests / tests (push) Successful in 2m18s
- Add CI step to create /dev/stdin symlinks before ISO build
  (Docker/container environments may lack these, causing mkinitcpio to fail)
- Remove stock linux kernel from packages.x86_64 (linux-cachyos is the
  intended kernel; dual-kernel causes boot confusion and doubles build time)

Closes #X
2026-09-17 09:42:29 +10:00
alvinlollo 48b760d54e Update cleanup step name to match always() behavior
Tests / tests (push) Successful in 2m15s
2026-09-17 07:30:20 +10:00
alvinlollo 7f91c189db Mirror releases and seed README in AlvinArch-releases for discovery
Tests / tests (push) Successful in 2m22s
Create a matching git tag + release in alvinlollo/AlvinArch-releases next to
the main repo release, seed a short README there pointing back to
AlvinArch (workflow status badges on top), and extend release pruning to
the releases repo so both stay capped at 3.
2026-09-16 22:44:05 +10:00