Author SHA1 Message Date
alvinlollo e57143c4bc docs/ci: implement yay 13 SIGSEGV workaround and update docs
Upstream pin check / quickshell-pin (push) Successful in 28s
Tests / tests (push) Successful in 3m31s
2026-10-12 12:57:37 +11:00
alvinlollo 3275ec9845 chore: add build runner CAP_SETFCAP check, fix MicroTeX compilation, and fix mono cert-sync
Upstream pin check / quickshell-pin (push) Successful in 18s
Tests / tests (push) Successful in 2m55s
2026-10-11 19:41:08 +11:00
5 changed files with 90 additions and 2 deletions
+17
View File
@@ -162,6 +162,23 @@ jobs:
rmdir "$d"
trap - EXIT
- name: Require CAP_SETFCAP for file capabilities
run: |
set -euo pipefail
# Without CAP_SETFCAP, pacstrap cannot restore security.capability
# xattrs ("unable to set CAP_SETFCAP effective capability"), so the
# live ISO silently ships newuidmap/newgidmap, snap-confine, dumpcap,
# kwin_wayland, ... without their capabilities. Fix the runner
# (e.g. allow CAP_SETFCAP in the gitea-runner service) rather than
# building a broken image.
eff="$(awk '/^CapEff:/{print $2}' /proc/self/status)"
if (( (16#$eff >> 31) & 1 )); then
echo "✅ CAP_SETFCAP is available (CapEff=$eff)"
else
echo "❌ CAP_SETFCAP missing (CapEff=$eff) - file capabilities would be dropped from the ISO" >&2
exit 1
fi
- name: Build Arch ISO
run: |
set -euo pipefail
+4
View File
@@ -110,6 +110,10 @@ whitespace.
- `airootfs/etc/skel/.config/illogical-impulse/presets/` carries the user's presets (`Laptop.json`, `Personal-Performance.json`, `Personal-Performance.zip`). They embed `/home/alvin/...` paths, so wallpapers/screenshots need fixing up after install.
- End-4 metapackages are built from `localrepo/end4-pkgbuilds/` (quickshell-git, bibata-modern-classic-bin, microtex-git).
- **quickshell pin / Qt 6.12**: end-4 pins quickshell to `41651d7` (Sep 25), which predates upstream fix `5d5d498` (Oct 3, *"use MOC includes instead of opaque pointer definitions — … Qt 6.12 compatibility"*). Arch shipped qt6 6.12.0 on Oct 8 and the old pin died with `Meta Types must be fully defined` in the moc build of quickshell-hyprland-ipc (failed CI run 137). `customize_airootfs.sh` therefore rewrites end-4's `_commit` to `11ca60be` after cloning — but **only** while it still matches `^_commit='41651d7`, so once end-4 bumps their own pin the guard goes inert and theirs wins. `localrepo/check-quickshell-pin.sh` (weekly `pin-check.yaml` job) fails CI if either pin goes stale or loses the fix; it warns instead of failing when end-4's known-stale pin is covered by the override.
- **MicroTeX flags**: the image's `makepkg.conf` is CachyOS's (`-march=native -O3`, LTO). GCC 16.2 hit an internal compiler error (segfault) on MicroTeX's `gtkmm_main.cpp` with it (failed CI run 155; not reproducible locally), so `customize_airootfs.sh` patches end-4's `illogical-impulse-microtex-git` PKGBUILD to `options=(!lto)` + `-O2` (our `localrepo/end4-pkgbuilds/microtex-git` carries the same).
- **CAP_SETFCAP on the runner**: without it pacstrap drops `security.capability` xattrs (newuidmap/newgidmap, snap-confine, dumpcap, kwin_wayland, ...) from the live ISO with only a warning. `build-iso.yaml` fails the job early if the runner lacks it — fix the runner, don't remove the check.
- **yay SIGSEGV on exit**: yay 13 (libalpm via purego/`dyalpm`) can segfault in `alpm_release()` *after* a finished transaction (failed CI run at end-4's `illogical-impulse-kde` step), which aborted `install-deps`. `customize_airootfs.sh` puts a temporary `yay` shim first on the builder's `PATH`: a failed plain `yay -S <pkgs>` counts as success only if `pacman -T` confirms every target is installed (it logs `[yay-shim]`). Every other failure keeps yay's exit code.
- mono's `cert-sync` runs before `ca-certificates.crt` exists during pacstrap, so `customize_airootfs.sh` (live) and `install_pacstrap` (target) re-run it.
- `/etc/skel/.zshrc` is owned by `grml-zsh-config`, so ours is staged as `airootfs/root/.zshrc-skel` and installed by `customize_airootfs.sh` after pacstrap — never add files under `airootfs/` at paths a package owns, or pacstrap aborts with "exists in filesystem".
- `packages.x86_64` is sorted alphabetically. Keep it sorted when adding/removing entries.
- `airootfs/opt/localrepo/` is a build artifact (gitignored) — never commit it.
+59 -2
View File
@@ -113,6 +113,18 @@ if [[ -f "${QS_PKG}" ]] && grep -q "^_commit='41651d7" "${QS_PKG}"; then
sed -i "s|^_commit='41651d7[^']*'|_commit='11ca60be22b063478ed9586ca1d7f92f0f261caf'|" "${QS_PKG}"
fi
# GCC 16.2 ICEs (segfault in ggc_set_mark) compiling MicroTeX's gtkmm_main.cpp
# - the LaTeX binary the package ships - under CachyOS's makepkg.conf
# (-march=native -O3 + -flto=auto), which killed CI run 155. Build it with -O2
# and no LTO; MicroTeX is tiny, the flags buy nothing. Re-running is a no-op.
MTX_PKG="${DOTS_REPO}/sdata/dist-arch/illogical-impulse-microtex-git/PKGBUILD"
if [[ -f "${MTX_PKG}" ]] && ! grep -q '^options=(!lto)' "${MTX_PKG}"; then
echo "[customize] Building MicroTeX with -O2 and no LTO (GCC 16 ICE)..."
# shellcheck disable=SC2016 # expanded by makepkg, not here
sed -i '/^build() {/a\ export CFLAGS="${CFLAGS//-O3/-O2}" CXXFLAGS="${CXXFLAGS//-O3/-O2}"' "${MTX_PKG}"
printf '\noptions=(!lto)\n' >> "${MTX_PKG}"
fi
# ── end4-pC: the default quickshell config, shipped in skel ──────────────────
# pctrade/end4-pC is a fork of the ii shell config. It lives next to ii in
# ~/.config/quickshell and does not modify it; which one runs is decided by
@@ -160,6 +172,36 @@ chmod 440 /etc/sudoers.d/99-ii-builder
# so the tree must be owned by the account that runs it.
chown -R "${BUILD_USER}:${BUILD_USER}" "${DOTS_REPO}"
# yay 13 (libalpm via purego/dyalpm) can SIGSEGV in alpm_release() at exit,
# *after* the transaction and its hooks completed (failed CI run: crash in
# dyalpm handle.Release). end-4 sees exit 2 and aborts. This shim, put first
# on PATH for the install-deps run only, turns a failed plain `yay -S <pkgs>`
# into success when every target is installed afterwards (pacman -T); any
# other failure keeps yay's exit code. It lives in /tmp and is removed after.
YAY_SHIM_DIR="$(mktemp -d /tmp/ii-yay-shim.XXXXXX)"
cat > "${YAY_SHIM_DIR}/yay" <<'EOF'
#!/bin/bash
"${YAY_SHIM_REAL:-/usr/bin/yay}" "$@"
rc=$?
(( rc == 0 )) && exit 0
sync=0
targets=()
for a in "$@"; do
case "$a" in
-S|--sync) sync=1 ;;
-S*) exit "$rc" ;; # -Ss/-Si/-Syu/...: not a plain install
-*) ;;
*) targets+=("$a") ;;
esac
done
if (( sync && ${#targets[@]} )) && pacman -T -- "${targets[@]}" >/dev/null; then
echo "[yay-shim] yay exited ${rc}, but all ${#targets[@]} targets are installed - continuing" >&2
exit 0
fi
exit "$rc"
EOF
chmod 755 "${YAY_SHIM_DIR}" "${YAY_SHIM_DIR}/yay"
# -f: never prompt (ask=false); -s: skip "pacman -Syu";
# --skip-plasmaintg: optional Firefox widget that pulls 410 pkgs / 526 MiB of
# KDE packages onto a non-KDE system;
@@ -168,11 +210,14 @@ chown -R "${BUILD_USER}:${BUILD_USER}" "${DOTS_REPO}"
# shellcheck disable=SC2024 # the redirect is meant for the child, not sudo
if ! sudo -u "${BUILD_USER}" env HOME="/home/${BUILD_USER}" \
GIT_TERMINAL_PROMPT=0 \
PATH="${YAY_SHIM_DIR}:/usr/local/sbin:/usr/local/bin:/usr/bin" \
bash -c "cd ${DOTS_REPO} && ./setup install-deps -f -s --skip-plasmaintg" \
< <(yes e); then
rm -rf "${YAY_SHIM_DIR}"
echo "[customize] end-4 ./setup install-deps failed" >&2
exit 1
fi
rm -rf "${YAY_SHIM_DIR}"
# ── Harvest the packages install-deps just built into the in-image local repo ─
# The live /etc/pacman.conf points [local-aur] at /opt/localrepo; without the
@@ -225,11 +270,13 @@ fi
# Rebuild the repo database (CI/update.sh ship a pre-built one alongside the
# packages) and refresh the live system's copy of it. No network needed: the
# remote repos were synced during pacstrap.
# remote repos were synced during pacstrap. No -R: the loop above already
# deleted the replaced archives, so repo-add's own cleanup only logged a
# spurious "Cannot remove file" ERROR.
local_pkgs=(/opt/localrepo/*.pkg.tar.zst)
if ((${#local_pkgs[@]} > 0)); then
echo "[customize] Rebuilding local-aur db (${#local_pkgs[@]} packages)..."
repo-add -R /opt/localrepo/local-aur.db.tar.gz "${local_pkgs[@]}"
repo-add /opt/localrepo/local-aur.db.tar.gz "${local_pkgs[@]}"
mkdir -p /var/lib/pacman/sync
cp -fL /opt/localrepo/local-aur.db /var/lib/pacman/sync/local-aur.db
if [[ -f /opt/localrepo/local-aur.files ]]; then
@@ -237,6 +284,16 @@ if ((${#local_pkgs[@]} > 0)); then
fi
fi
# ── mono certificate store ──────────────────────────────────────────────────
# mono's post_install runs cert-sync during pacstrap, before the
# post-transaction hook has generated ca-certificates.crt, so the store ships
# empty ("Couldn't retrieve the file") and mono apps reject every TLS cert.
if command -v cert-sync &>/dev/null; then
echo "[customize] Populating mono certificate store..."
cert-sync --quiet /etc/ssl/certs/ca-certificates.crt \
|| echo "[customize] WARNING: cert-sync failed, mono store left empty" >&2
fi
# ── makepkg leftovers + throwaway account do not belong in the ISO ──────────
if [[ -d "${DOTS_REPO}/sdata/dist-arch" ]]; then
find "${DOTS_REPO}/sdata/dist-arch" -mindepth 2 -maxdepth 2 -type d \
+7
View File
@@ -743,6 +743,13 @@ install_pacstrap() {
pacstrap "$TARGET" "${pkgs[@]}" --noconfirm \
|| die "pacstrap failed - the target system is incomplete (output above, full log: $LOG)."
# mono's post_install runs cert-sync before the post-transaction hook has
# generated ca-certificates.crt, leaving mono's certificate store empty.
if [[ -x "${TARGET}/usr/bin/cert-sync" ]]; then
arch-chroot "$TARGET" cert-sync --quiet /etc/ssl/certs/ca-certificates.crt \
>> "$LOG" 2>&1 || warn "cert-sync failed - mono apps may reject TLS certificates."
fi
ok "Packages installed."
}
@@ -18,6 +18,8 @@ depends=(
makedepends=("git" "cmake")
source=("git+${url}.git")
sha256sums=("SKIP")
# -O3 + LTO (CachyOS makepkg.conf) make GCC 16.2 ICE on gtkmm_main.cpp
options=(!lto)
prepare() {
cd $_pkgname
@@ -26,6 +28,7 @@ prepare() {
}
build() {
export CFLAGS="${CFLAGS//-O3/-O2}" CXXFLAGS="${CXXFLAGS//-O3/-O2}"
cd $_pkgname
cmake -B build -S . -DCMAKE_BUILD_TYPE=None
cmake --build build