Files
marfrit-packages/.gitea/workflows/build.yml
T
marfrit 051da5e8dc libva-v4l2-request-fourier-debian: switch to debian-aarch64-bohr runner
Per @marfrit on PR #44 review: a native Debian trixie aarch64 runner
(debian-aarch64-bohr) is available — use it instead of the sysroot
hack from the previous commit.

The sysroot approach worked but was a workaround for not having the
right runner.  Native trixie runner is much cleaner:

  - libva-dev installs via apt-get directly from trixie's archive
    (2.22.0-3) — pkg-config returns trixie headers, driver compiles
    in __vaDriverInit_1_22 naturally.
  - No need to symlink libva.so.2 -> libva.so or rewrite .pc prefixes.
  - No bsdtar/ar/dpkg-deb juggling on an Arch runner that doesn't
    natively have dpkg.

Changes from PR v1:

  - .gitea/workflows/build.yml: libva-v4l2-request-fourier-debian
    runs-on: debian-aarch64-bohr (was arch-aarch64).  Build-deps
    installed via apt-get instead of pacman -Syu.

  - build-deb.sh: drop the sysroot download / pkgconfig rewrite /
    symlink block.  Keep the post-build ABI sanity check (nm -D |
    grep __vaDriverInit_1_22) — same defensive role as before, with
    an updated error message that points to the expected runner.

  - debian/.../changelog: -2 entry rewritten to describe the runner
    move instead of the sysroot.

Tested approach on boltzmann (aarch64): meson build against trixie
sysroot produces __vaDriverInit_1_22 (proves the source compiles
correctly with VA-API 1.22 headers).  Native runner build will
follow the same path, just without the explicit sysroot setup.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 14:58:37 +02:00

1411 lines
59 KiB
YAML

name: build and publish packages
on:
push:
branches: [main]
paths:
- 'arch/**'
- 'debian/**'
- '.gitea/workflows/**'
workflow_dispatch:
jobs:
distcc-avahi-aarch64:
runs-on: arch-aarch64
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/distcc-avahi)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo avahi popt python python-setuptools
- name: import signing key
if: steps.skip-check.outputs.skip != '1'
env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
run: |
set -e
gpgconf --homedir /root/.gnupg --kill all 2>/dev/null || true
rm -rf /root/.gnupg /root/repo_pass
mkdir -m700 -p /root/.gnupg
printf '%s' "$PASS" > /root/repo_pass
chmod 600 /root/repo_pass
printf '%s\n' "$PRIV" | gpg --batch --import
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519
chmod 600 /root/.ssh/id_ed25519
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg distcc-avahi
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
rm -rf /tmp/build-distcc-avahi
cp -r arch/distcc-avahi /tmp/build-distcc-avahi
chown -R builder:builder /tmp/build-distcc-avahi
cd /tmp/build-distcc-avahi
sudo -u builder -H makepkg --nocheck --noconfirm --syncdeps --cleanbuild
ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign distcc-avahi
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd /tmp/build-distcc-avahi
for f in *.pkg.tar.xz *.pkg.tar.zst *.pkg.tar.gz; do
[ -f "$f" ] || continue
gpg --batch --pinentry-mode loopback --passphrase-file /root/repo_pass \
--detach-sign --yes -u 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C "$f"
done
- name: update aarch64 repo db
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
mkdir -p /tmp/arch-stage
cd /tmp/arch-stage
rm -f *
for f in marfrit.db.tar.gz marfrit.db.tar.gz.sig marfrit.files.tar.gz marfrit.files.tar.gz.sig; do
curl -sSLf "https://packages.reauktion.de/arch/aarch64/$f" -o "$f" || rm -f "$f"
done
for ext in xz zst gz; do
ls /tmp/build-distcc-avahi/*.pkg.tar.$ext 2>/dev/null && \
mv /tmp/build-distcc-avahi/*.pkg.tar.$ext /tmp/build-distcc-avahi/*.pkg.tar.$ext.sig .
done || true
export GNUPGHOME=/root/.gnupg
printf 'pinentry-mode loopback\npassphrase-file /root/repo_pass\n' > /root/.gnupg/gpg.conf
printf 'allow-loopback-pinentry\n' > /root/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
pkgs=()
for ext in xz zst gz; do
for f in *.pkg.tar.$ext; do [ -f "$f" ] && pkgs+=("$f"); done
done
# Force-replace db entries: remove the package by name first so the
# subsequent --new add records this build's CSIZE/SHA256, not the
# previous build's. (makepkg output isn't byte-stable across runs.)
if [ -f marfrit.db.tar.gz ]; then
for f in "${pkgs[@]}"; do
name=$(echo "$f" | sed -E 's/-[0-9].*//')
repo-remove --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
marfrit.db.tar.gz "$name" 2>/dev/null || true
done
fi
repo-add --new --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
--verify marfrit.db.tar.gz "${pkgs[@]}"
ln -sf marfrit.db.tar.gz marfrit.db
ln -sf marfrit.files.tar.gz marfrit.files
ln -sf marfrit.db.tar.gz.sig marfrit.db.sig
# marfrit.files isn't signed by repo-add (pacman only verifies .db)
rm -f marfrit.files.sig
- name: publish to aarch64
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd /tmp/arch-stage
retry rsync -avL --copy-unsafe-links \
-e 'ssh -i /root/.ssh/id_ed25519' \
./ mfritsche@nc.reauktion.de:arch/aarch64/
- name: wipe secrets
if: always()
run: rm -f /root/repo_pass /root/.ssh/id_ed25519 /root/.ssh/id_ed25519_hertz
# -------------------------------------------------------------------------
# lmcp Debian (Architecture: all) — built on the aarch64 runner using
# dpkg-deb (Arch ships dpkg in extra). The .deb is rsynced to hertz's
# incoming dir, then we trigger 'publish-deb' on hertz which runs
# reprepro and mirrors dists/+pool/ to nc.
# -------------------------------------------------------------------------
lmcp-debian:
needs: lmcp-any # serialize after the Arch build to share the runner
runs-on: arch-aarch64
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/lmcp)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install dpkg
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed dpkg openssh rsync curl
- name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519_hertz
chmod 600 /root/.ssh/id_ed25519_hertz
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build lmcp .deb
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd debian/lmcp
./build-deb.sh
ls -la *.deb
- name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd debian/lmcp
DEB=$(ls lmcp_*.deb | head -1)
# Push the .deb into hertz's incoming dir via rrsync.
retry rsync -av -e 'ssh -i /root/.ssh/id_ed25519_hertz' "$DEB" \
marfritrepo@hertz.fritz.box:
# Trigger reprepro for each suite.
for suite in bookworm trixie; do
retry ssh -i /root/.ssh/id_ed25519_hertz marfritrepo@hertz.fritz.box \
"publish-deb $suite $DEB"
done
- name: wipe secrets
if: always()
run: rm -f /root/.ssh/id_ed25519_hertz
# -------------------------------------------------------------------------
# lmcp is pure Lua (arch=any). One build on the aarch64 runner produces a
# package that's valid on every pacman-based target, so we publish the same
# .pkg.tar.* to both /arch/aarch64/ and /arch/x86_64/ after rebuilding each
# db with the package registered.
# -------------------------------------------------------------------------
lmcp-any:
needs: distcc-avahi-aarch64 # serialize on shared aarch64 db; expand later
runs-on: arch-aarch64
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/lmcp)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo lua lua-socket
- name: import signing key
if: steps.skip-check.outputs.skip != '1'
env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
run: |
set -e
gpgconf --homedir /root/.gnupg --kill all 2>/dev/null || true
rm -rf /root/.gnupg /root/repo_pass
mkdir -m700 -p /root/.gnupg
printf '%s' "$PASS" > /root/repo_pass
chmod 600 /root/repo_pass
printf '%s\n' "$PRIV" | gpg --batch --import
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519
chmod 600 /root/.ssh/id_ed25519
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg lmcp
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
rm -rf /tmp/build-lmcp
cp -r arch/lmcp /tmp/build-lmcp
chown -R builder:builder /tmp/build-lmcp
cd /tmp/build-lmcp
sudo -u builder -H makepkg --nocheck --noconfirm --syncdeps --cleanbuild
ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign lmcp
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd /tmp/build-lmcp
for f in *.pkg.tar.xz *.pkg.tar.zst *.pkg.tar.gz; do
[ -f "$f" ] || continue
gpg --batch --pinentry-mode loopback --passphrase-file /root/repo_pass \
--detach-sign --yes -u 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C "$f"
done
- name: publish lmcp to both arches
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
export GNUPGHOME=/root/.gnupg
printf 'pinentry-mode loopback\npassphrase-file /root/repo_pass\n' > /root/.gnupg/gpg.conf
printf 'allow-loopback-pinentry\n' > /root/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
for target in aarch64 x86_64; do
stage="/tmp/arch-stage-$target"
rm -rf "$stage"; mkdir -p "$stage"; cd "$stage"
for f in marfrit.db.tar.gz marfrit.db.tar.gz.sig marfrit.files.tar.gz marfrit.files.tar.gz.sig; do
curl -sSLf "https://packages.reauktion.de/arch/$target/$f" -o "$f" || rm -f "$f"
done
cp /tmp/build-lmcp/*.pkg.tar.* .
pkgs=()
for ext in xz zst gz; do
for f in *.pkg.tar.$ext; do [ -f "$f" ] && pkgs+=("$f"); done
done
if [ -f marfrit.db.tar.gz ]; then
for f in "${pkgs[@]}"; do
name=$(echo "$f" | sed -E 's/-[0-9].*//')
repo-remove --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
marfrit.db.tar.gz "$name" 2>/dev/null || true
done
fi
repo-add --new --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
--verify marfrit.db.tar.gz "${pkgs[@]}"
ln -sf marfrit.db.tar.gz marfrit.db
ln -sf marfrit.files.tar.gz marfrit.files
ln -sf marfrit.db.tar.gz.sig marfrit.db.sig
ln -sf marfrit.files.tar.gz.sig marfrit.files.sig
retry rsync -avL --copy-unsafe-links \
-e 'ssh -i /root/.ssh/id_ed25519' \
./ "mfritsche@nc.reauktion.de:arch/$target/"
done
- name: wipe secrets
if: always()
run: rm -f /root/repo_pass /root/.ssh/id_ed25519
# -------------------------------------------------------------------------
# claude-his-agent (arch=any) — pure markdown + shell, one pkg valid on all
# pacman targets. Same dual-arch publish trick as lmcp.
# -------------------------------------------------------------------------
claude-his-any:
needs: lmcp-debian
runs-on: arch-aarch64
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/claude-his-agent)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo
- name: import signing key
if: steps.skip-check.outputs.skip != '1'
env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
run: |
set -e
gpgconf --homedir /root/.gnupg --kill all 2>/dev/null || true
rm -rf /root/.gnupg /root/repo_pass
mkdir -m700 -p /root/.gnupg
printf '%s' "$PASS" > /root/repo_pass
chmod 600 /root/repo_pass
printf '%s\n' "$PRIV" | gpg --batch --import
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519
chmod 600 /root/.ssh/id_ed25519
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg claude-his-agent
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
rm -rf /tmp/build-his
cp -r arch/claude-his-agent /tmp/build-his
chown -R builder:builder /tmp/build-his
cd /tmp/build-his
sudo -u builder -H makepkg --nocheck --noconfirm --syncdeps --cleanbuild
ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign claude-his-agent
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd /tmp/build-his
for f in *.pkg.tar.xz *.pkg.tar.zst *.pkg.tar.gz; do
[ -f "$f" ] || continue
gpg --batch --pinentry-mode loopback --passphrase-file /root/repo_pass \
--detach-sign --yes -u 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C "$f"
done
- name: publish claude-his-agent to both arches
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
export GNUPGHOME=/root/.gnupg
printf 'pinentry-mode loopback\npassphrase-file /root/repo_pass\n' > /root/.gnupg/gpg.conf
printf 'allow-loopback-pinentry\n' > /root/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
for target in aarch64 x86_64; do
stage="/tmp/arch-stage-his-$target"
rm -rf "$stage"; mkdir -p "$stage"; cd "$stage"
for f in marfrit.db.tar.gz marfrit.db.tar.gz.sig marfrit.files.tar.gz marfrit.files.tar.gz.sig; do
curl -sSLf "https://packages.reauktion.de/arch/$target/$f" -o "$f" || rm -f "$f"
done
cp /tmp/build-his/*.pkg.tar.* .
pkgs=()
for ext in xz zst gz; do
for f in *.pkg.tar.$ext; do [ -f "$f" ] && pkgs+=("$f"); done
done
if [ -f marfrit.db.tar.gz ]; then
for f in "${pkgs[@]}"; do
name=$(echo "$f" | sed -E 's/-[0-9].*//')
repo-remove --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
marfrit.db.tar.gz "$name" 2>/dev/null || true
done
fi
repo-add --new --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
--verify marfrit.db.tar.gz "${pkgs[@]}"
ln -sf marfrit.db.tar.gz marfrit.db
ln -sf marfrit.files.tar.gz marfrit.files
ln -sf marfrit.db.tar.gz.sig marfrit.db.sig
ln -sf marfrit.files.tar.gz.sig marfrit.files.sig
retry rsync -avL --copy-unsafe-links \
-e 'ssh -i /root/.ssh/id_ed25519' \
./ "mfritsche@nc.reauktion.de:arch/$target/"
done
- name: wipe secrets
if: always()
run: rm -f /root/repo_pass /root/.ssh/id_ed25519
# -------------------------------------------------------------------------
# ffmpeg-v4l2-request-fourier (aarch64 only) — FFmpeg with V4L2 Request API
# hwaccel for Rockchip / Allwinner stateless decoders. Used by the Fourier
# umbrella (ohm, fresnel, ampere). Long-running build, so failures don't
# block downstream debian jobs.
# -------------------------------------------------------------------------
ffmpeg-v4l2-request-aarch64:
needs: claude-his-any
runs-on: arch-aarch64
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/ffmpeg-v4l2-request-fourier)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo nasm
- name: import signing key
if: steps.skip-check.outputs.skip != '1'
env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
run: |
set -e
gpgconf --homedir /root/.gnupg --kill all 2>/dev/null || true
rm -rf /root/.gnupg /root/repo_pass
mkdir -m700 -p /root/.gnupg
printf '%s' "$PASS" > /root/repo_pass
chmod 600 /root/repo_pass
printf '%s\n' "$PRIV" | gpg --batch --import
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519
chmod 600 /root/.ssh/id_ed25519
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg ffmpeg-v4l2-request-fourier
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
rm -rf /tmp/build-ffmpeg-v4l2
cp -r arch/ffmpeg-v4l2-request-fourier /tmp/build-ffmpeg-v4l2
chown -R builder:builder /tmp/build-ffmpeg-v4l2
cd /tmp/build-ffmpeg-v4l2
# Parallelise wide; distcc-avahi distributes compiles across the
# zeroconf pool (tesla, dcc1, dcc2, boltzmann ≈ 60 logical cores).
sudo -u builder -H env MAKEFLAGS="-j60" \
makepkg --nocheck --noconfirm --syncdeps --cleanbuild
ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign ffmpeg-v4l2-request-fourier
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd /tmp/build-ffmpeg-v4l2
for f in *.pkg.tar.xz *.pkg.tar.zst *.pkg.tar.gz; do
[ -f "$f" ] || continue
gpg --batch --pinentry-mode loopback --passphrase-file /root/repo_pass \
--detach-sign --yes -u 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C "$f"
done
- name: update aarch64 repo db
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
mkdir -p /tmp/arch-stage-ffmpeg
cd /tmp/arch-stage-ffmpeg
rm -f *
for f in marfrit.db.tar.gz marfrit.db.tar.gz.sig marfrit.files.tar.gz marfrit.files.tar.gz.sig; do
curl -sSLf "https://packages.reauktion.de/arch/aarch64/$f" -o "$f" || rm -f "$f"
done
for ext in xz zst gz; do
ls /tmp/build-ffmpeg-v4l2/*.pkg.tar.$ext 2>/dev/null && \
mv /tmp/build-ffmpeg-v4l2/*.pkg.tar.$ext /tmp/build-ffmpeg-v4l2/*.pkg.tar.$ext.sig .
done || true
export GNUPGHOME=/root/.gnupg
printf 'pinentry-mode loopback\npassphrase-file /root/repo_pass\n' > /root/.gnupg/gpg.conf
printf 'allow-loopback-pinentry\n' > /root/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
pkgs=()
for ext in xz zst gz; do
for f in *.pkg.tar.$ext; do [ -f "$f" ] && pkgs+=("$f"); done
done
if [ -f marfrit.db.tar.gz ]; then
for f in "${pkgs[@]}"; do
name=$(echo "$f" | sed -E 's/-[0-9].*//')
repo-remove --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
marfrit.db.tar.gz "$name" 2>/dev/null || true
done
fi
repo-add --new --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
--verify marfrit.db.tar.gz "${pkgs[@]}"
ln -sf marfrit.db.tar.gz marfrit.db
ln -sf marfrit.files.tar.gz marfrit.files
ln -sf marfrit.db.tar.gz.sig marfrit.db.sig
rm -f marfrit.files.sig
- name: publish to aarch64
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd /tmp/arch-stage-ffmpeg
retry rsync -avL --copy-unsafe-links \
-e 'ssh -i /root/.ssh/id_ed25519' \
./ mfritsche@nc.reauktion.de:arch/aarch64/
- name: wipe secrets
if: always()
run: rm -f /root/repo_pass /root/.ssh/id_ed25519
# -------------------------------------------------------------------------
# libva-v4l2-request-fourier (aarch64 only) — VA-API V4L2-stateless backend,
# multiplanar fork. Successor to libva-v4l2-request-ohm-gl-fix (never
# published). Tracks the campaign fork's git tip directly; pinned commit
# is the libva-multiplanar iter8 close.
# -------------------------------------------------------------------------
libva-v4l2-request-fourier-aarch64:
needs: ffmpeg-v4l2-request-aarch64
runs-on: arch-aarch64
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/libva-v4l2-request-fourier)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo
- name: import signing key
if: steps.skip-check.outputs.skip != '1'
env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
run: |
set -e
gpgconf --homedir /root/.gnupg --kill all 2>/dev/null || true
rm -rf /root/.gnupg /root/repo_pass
mkdir -m700 -p /root/.gnupg
printf '%s' "$PASS" > /root/repo_pass
chmod 600 /root/repo_pass
printf '%s\n' "$PRIV" | gpg --batch --import
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519
chmod 600 /root/.ssh/id_ed25519
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg libva-v4l2-request-fourier
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
rm -rf /tmp/build-libva-v4l2
cp -r arch/libva-v4l2-request-fourier /tmp/build-libva-v4l2
chown -R builder:builder /tmp/build-libva-v4l2
cd /tmp/build-libva-v4l2
sudo -u builder -H env MAKEFLAGS="-j60" \
makepkg --nocheck --noconfirm --syncdeps --cleanbuild
ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign libva-v4l2-request-fourier
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd /tmp/build-libva-v4l2
for f in *.pkg.tar.xz *.pkg.tar.zst *.pkg.tar.gz; do
[ -f "$f" ] || continue
gpg --batch --pinentry-mode loopback --passphrase-file /root/repo_pass \
--detach-sign --yes -u 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C "$f"
done
- name: update aarch64 repo db
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
mkdir -p /tmp/arch-stage-libva
cd /tmp/arch-stage-libva
rm -f *
for f in marfrit.db.tar.gz marfrit.db.tar.gz.sig marfrit.files.tar.gz marfrit.files.tar.gz.sig; do
curl -sSLf "https://packages.reauktion.de/arch/aarch64/$f" -o "$f" || rm -f "$f"
done
for ext in xz zst gz; do
ls /tmp/build-libva-v4l2/*.pkg.tar.$ext 2>/dev/null && \
mv /tmp/build-libva-v4l2/*.pkg.tar.$ext /tmp/build-libva-v4l2/*.pkg.tar.$ext.sig .
done || true
export GNUPGHOME=/root/.gnupg
printf 'pinentry-mode loopback\npassphrase-file /root/repo_pass\n' > /root/.gnupg/gpg.conf
printf 'allow-loopback-pinentry\n' > /root/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
pkgs=()
for ext in xz zst gz; do
for f in *.pkg.tar.$ext; do [ -f "$f" ] && pkgs+=("$f"); done
done
if [ -f marfrit.db.tar.gz ]; then
for f in "${pkgs[@]}"; do
name=$(echo "$f" | sed -E 's/-[0-9].*//')
repo-remove --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
marfrit.db.tar.gz "$name" 2>/dev/null || true
done
fi
repo-add --new --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
--verify marfrit.db.tar.gz "${pkgs[@]}"
ln -sf marfrit.db.tar.gz marfrit.db
ln -sf marfrit.files.tar.gz marfrit.files
ln -sf marfrit.db.tar.gz.sig marfrit.db.sig
rm -f marfrit.files.sig
- name: publish to aarch64
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd /tmp/arch-stage-libva
retry rsync -avL --copy-unsafe-links \
-e 'ssh -i /root/.ssh/id_ed25519' \
./ mfritsche@nc.reauktion.de:arch/aarch64/
- name: wipe secrets
if: always()
run: rm -f /root/repo_pass /root/.ssh/id_ed25519
# -------------------------------------------------------------------------
# mpv-fourier (aarch64 only) — mpv with fourier-umbrella patches.
# Patch slot exists for the vo_dmabuf_wayland plane-semantics fix per
# marfrit/dmabuf-modifier-triage#1. Initial scaffold builds vanilla
# mpv 0.41.0 — bump pkgrel and add patch to source=() when iter1 lands.
# -------------------------------------------------------------------------
mpv-fourier-aarch64:
needs: libva-v4l2-request-fourier-aarch64
runs-on: arch-aarch64
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/mpv-fourier)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo
- name: import signing key
if: steps.skip-check.outputs.skip != '1'
env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
run: |
set -e
gpgconf --homedir /root/.gnupg --kill all 2>/dev/null || true
rm -rf /root/.gnupg /root/repo_pass
mkdir -m700 -p /root/.gnupg
printf '%s' "$PASS" > /root/repo_pass
chmod 600 /root/repo_pass
printf '%s\n' "$PRIV" | gpg --batch --import
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519
chmod 600 /root/.ssh/id_ed25519
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: configure [marfrit] repo + pre-install ffmpeg-v4l2-request-fourier
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
# mpv-fourier links libavcodec at build time. If the build host pulls
# stock arch's ffmpeg, the resulting binary's libavcodec ABI version
# drifts from the marfrit ffmpeg-v4l2-request-fourier that consumer
# hosts (ohm) install. Force build-time consistency by configuring
# [marfrit] on fermi and pre-installing our ffmpeg before makepkg.
curl -sLo /tmp/marfrit.gpg https://packages.reauktion.de/marfrit.gpg
pacman-key --add /tmp/marfrit.gpg
pacman-key --lsign-key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C
rm -f /tmp/marfrit.gpg
if ! grep -q '^\[marfrit\]' /etc/pacman.conf; then
printf '\n[marfrit]\nServer = https://packages.reauktion.de/arch/$arch\nSigLevel = Required\n' >> /etc/pacman.conf
fi
pacman -Sy --noconfirm
# Drop any cached ffmpeg-v4l2-request-fourier that may be corrupt
# from a prior interrupted build (the ccache misadventure left
# one such file behind).
rm -f /var/cache/pacman/pkg/ffmpeg-v4l2-request-fourier-*-aarch64.pkg.tar.*
# Stock arch ffmpeg may already be installed from a prior fermi job;
# pacman -S --noconfirm defaults the [y/N] conflict prompt to N.
# Use printf (finite stream, exits 0 cleanly) — `yes y | ...` would
# work but fails under bash pipefail when yes catches SIGPIPE.
# Three y's covers: "Remove conflict?", "Proceed?", any keyring prompt.
printf 'y\ny\ny\n' | pacman -S marfrit/ffmpeg-v4l2-request-fourier
- name: makepkg mpv-fourier
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
rm -rf /tmp/build-mpv
cp -r arch/mpv-fourier /tmp/build-mpv
chown -R builder:builder /tmp/build-mpv
cd /tmp/build-mpv
sudo -u builder -H env MAKEFLAGS="-j60" \
makepkg --nocheck --noconfirm --syncdeps --cleanbuild
ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign mpv-fourier
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd /tmp/build-mpv
for f in *.pkg.tar.xz *.pkg.tar.zst *.pkg.tar.gz; do
[ -f "$f" ] || continue
gpg --batch --pinentry-mode loopback --passphrase-file /root/repo_pass \
--detach-sign --yes -u 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C "$f"
done
- name: update aarch64 repo db
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
mkdir -p /tmp/arch-stage-mpv
cd /tmp/arch-stage-mpv
rm -f *
for f in marfrit.db.tar.gz marfrit.db.tar.gz.sig marfrit.files.tar.gz marfrit.files.tar.gz.sig; do
curl -sSLf "https://packages.reauktion.de/arch/aarch64/$f" -o "$f" || rm -f "$f"
done
for ext in xz zst gz; do
ls /tmp/build-mpv/*.pkg.tar.$ext 2>/dev/null && \
mv /tmp/build-mpv/*.pkg.tar.$ext /tmp/build-mpv/*.pkg.tar.$ext.sig .
done || true
export GNUPGHOME=/root/.gnupg
printf 'pinentry-mode loopback\npassphrase-file /root/repo_pass\n' > /root/.gnupg/gpg.conf
printf 'allow-loopback-pinentry\n' > /root/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
pkgs=()
for ext in xz zst gz; do
for f in *.pkg.tar.$ext; do [ -f "$f" ] && pkgs+=("$f"); done
done
if [ -f marfrit.db.tar.gz ]; then
for f in "${pkgs[@]}"; do
name=$(echo "$f" | sed -E 's/-[0-9].*//')
repo-remove --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
marfrit.db.tar.gz "$name" 2>/dev/null || true
done
fi
repo-add --new --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
--verify marfrit.db.tar.gz "${pkgs[@]}"
ln -sf marfrit.db.tar.gz marfrit.db
ln -sf marfrit.files.tar.gz marfrit.files
ln -sf marfrit.db.tar.gz.sig marfrit.db.sig
rm -f marfrit.files.sig
- name: publish to aarch64
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd /tmp/arch-stage-mpv
retry rsync -avL --copy-unsafe-links \
-e 'ssh -i /root/.ssh/id_ed25519' \
./ mfritsche@nc.reauktion.de:arch/aarch64/
- name: wipe secrets
if: always()
run: rm -f /root/repo_pass /root/.ssh/id_ed25519
# -------------------------------------------------------------------------
# claude-his-agent Debian (Architecture: all) — same dpkg-deb pattern as
# lmcp-debian; publishes to bookworm + trixie via hertz reprepro.
# -------------------------------------------------------------------------
claude-his-debian:
needs: claude-his-any
runs-on: arch-aarch64
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/claude-his-agent)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install dpkg
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed dpkg openssh rsync curl
- name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519_hertz
chmod 600 /root/.ssh/id_ed25519_hertz
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build claude-his-agent .deb
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd debian/claude-his-agent
./build-deb.sh
ls -la *.deb
- name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd debian/claude-his-agent
DEB=$(ls claude-his-agent_*.deb | head -1)
retry rsync -av -e 'ssh -i /root/.ssh/id_ed25519_hertz' "$DEB" \
marfritrepo@hertz.fritz.box:
for suite in bookworm trixie; do
retry ssh -i /root/.ssh/id_ed25519_hertz marfritrepo@hertz.fritz.box \
"publish-deb $suite $DEB"
done
- name: wipe secrets
if: always()
run: rm -f /root/.ssh/id_ed25519_hertz
# -------------------------------------------------------------------------
# ffmpeg-v4l2-request-fourier Debian (aarch64) — debian/<pkg>/build-deb.sh
# builds the Kwiboo FFmpeg fork natively on the arch-aarch64 runner using
# the arch toolchain + system libs, then dpkg-deb's the result. Resulting
# .deb is rsynced to hertz; reprepro publishes into bookworm + trixie.
# -------------------------------------------------------------------------
ffmpeg-v4l2-request-debian:
needs: ffmpeg-v4l2-request-aarch64
runs-on: arch-aarch64
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/ffmpeg-v4l2-request-fourier)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install build-deps (Arch pkg names; build-deb.sh links natively)
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed \
dpkg openssh rsync curl base-devel git nasm yasm \
linux-api-headers mesa alsa-lib bzip2 fontconfig fribidi gmp \
gnutls lame libass dav1d libdrm freetype2 libpulse libva \
libvorbis libvpx libwebp x264 x265 libxml2 opus v4l-utils xz zlib
- name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519_hertz
chmod 600 /root/.ssh/id_ed25519_hertz
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build ffmpeg-v4l2-request-fourier .deb
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd debian/ffmpeg-v4l2-request-fourier
./build-deb.sh
ls -la *.deb
- name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd debian/ffmpeg-v4l2-request-fourier
DEB=$(ls ffmpeg-v4l2-request-fourier_*.deb | head -1)
retry rsync -av -e 'ssh -i /root/.ssh/id_ed25519_hertz' "$DEB" \
marfritrepo@hertz.fritz.box:
for suite in bookworm trixie; do
retry ssh -i /root/.ssh/id_ed25519_hertz marfritrepo@hertz.fritz.box \
"publish-deb $suite $DEB"
done
- name: wipe secrets
if: always()
run: rm -f /root/.ssh/id_ed25519_hertz
# -------------------------------------------------------------------------
# libva-v4l2-request-fourier Debian (aarch64) — meson build + dpkg-deb wrap.
# -------------------------------------------------------------------------
libva-v4l2-request-fourier-debian:
needs: libva-v4l2-request-fourier-aarch64
# Native Debian trixie runner — the driver bakes __vaDriverInit_1_<MINOR>
# at compile time from <va/va.h>. Building on Arch (libva 2.23) produced
# __vaDriverInit_1_23, which trixie's libva 2.22 runtime cannot bind: the
# .deb installed but vaInitialize() returned -1 on every host. A native
# trixie runner avoids the cross-distro ABI skew entirely.
runs-on: debian-aarch64-bohr
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/libva-v4l2-request-fourier)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install build-deps
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
export DEBIAN_FRONTEND=noninteractive
retry apt-get update -qq
retry apt-get install -y --no-install-recommends \
build-essential meson ninja-build pkg-config \
libva-dev libdrm-dev \
curl openssh-client rsync ca-certificates git dpkg-dev
- name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519_hertz
chmod 600 /root/.ssh/id_ed25519_hertz
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build libva-v4l2-request-fourier .deb
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd debian/libva-v4l2-request-fourier
./build-deb.sh
ls -la *.deb
- name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd debian/libva-v4l2-request-fourier
DEB=$(ls libva-v4l2-request-fourier_*.deb | head -1)
retry rsync -av -e 'ssh -i /root/.ssh/id_ed25519_hertz' "$DEB" \
marfritrepo@hertz.fritz.box:
for suite in bookworm trixie; do
retry ssh -i /root/.ssh/id_ed25519_hertz marfritrepo@hertz.fritz.box \
"publish-deb $suite $DEB"
done
- name: wipe secrets
if: always()
run: rm -f /root/.ssh/id_ed25519_hertz
# -------------------------------------------------------------------------
# mpv-fourier Debian (aarch64) — meson build links against
# ffmpeg-v4l2-request-fourier's libavcodec to keep ABI symmetry between
# the .deb's runtime dep declaration and the binary's actual linkage.
# We pre-install the Arch sibling package from [marfrit] for that.
# -------------------------------------------------------------------------
mpv-fourier-debian:
needs: mpv-fourier-aarch64
runs-on: arch-aarch64
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/mpv-fourier)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install build-deps
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed \
dpkg openssh rsync curl base-devel git meson ninja python-docutils \
ladspa wayland-protocols vulkan-headers \
alsa-lib desktop-file-utils glibc hicolor-icon-theme jack lcms2 \
libarchive libass libbluray libcdio libcdio-paranoia libdisplay-info \
libdrm libdvdnav libdvdread libegl libgl libglvnd libjpeg-turbo \
libplacebo libpulse libsixel libva libvdpau libx11 libxext \
libxkbcommon libxpresent libxrandr libxss libxv luajit mesa mujs \
libpipewire rubberband sdl2 openal uchardet vapoursynth \
vulkan-icd-loader wayland zlib
- name: configure [marfrit] repo + pre-install ffmpeg-v4l2-request-fourier
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
curl -sLo /tmp/marfrit.gpg https://packages.reauktion.de/marfrit.gpg
pacman-key --add /tmp/marfrit.gpg
pacman-key --lsign-key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C
rm -f /tmp/marfrit.gpg
if ! grep -q '^\[marfrit\]' /etc/pacman.conf; then
printf '\n[marfrit]\nServer = https://packages.reauktion.de/arch/$arch\nSigLevel = Required\n' >> /etc/pacman.conf
fi
pacman -Sy --noconfirm
rm -f /var/cache/pacman/pkg/ffmpeg-v4l2-request-fourier-*-aarch64.pkg.tar.*
printf 'y\ny\ny\n' | pacman -S marfrit/ffmpeg-v4l2-request-fourier
- name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519_hertz
chmod 600 /root/.ssh/id_ed25519_hertz
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build mpv-fourier .deb
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd debian/mpv-fourier
./build-deb.sh
ls -la *.deb
- name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd debian/mpv-fourier
DEB=$(ls mpv-fourier_*.deb | head -1)
retry rsync -av -e 'ssh -i /root/.ssh/id_ed25519_hertz' "$DEB" \
marfritrepo@hertz.fritz.box:
for suite in bookworm trixie; do
retry ssh -i /root/.ssh/id_ed25519_hertz marfritrepo@hertz.fritz.box \
"publish-deb $suite $DEB"
done
- name: wipe secrets
if: always()
run: rm -f /root/.ssh/id_ed25519_hertz
# -------------------------------------------------------------------------
# daedalus-v4l2 Debian (aarch64) — CMake + Make build, dpkg-deb wrap.
# Userspace daemon + test tools for the daedalus_v4l2 V4L2-stateless shim.
# -------------------------------------------------------------------------
daedalus-v4l2-debian:
needs: claude-his-debian
runs-on: arch-aarch64
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/daedalus-v4l2)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install build-deps (sans ffmpeg — see [marfrit] step)
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
# Do NOT pull stock 'ffmpeg' here: the arch-aarch64 runner has
# ffmpeg-v4l2-request-fourier pre-installed from the mpv-aarch64
# job (configured via [marfrit]), and pacman -S ffmpeg would
# conflict on the libav* drop-in. Daedalus build only needs
# libavcodec/libavformat headers, which the fourier package
# already supplies. Keep cmake/ninja/pkgconf/libdrm here; the
# ffmpeg-dev equivalent comes via the next step.
retry pacman -Syu --noconfirm --needed \
dpkg openssh rsync curl base-devel git cmake ninja pkgconf \
libdrm
- name: ensure ffmpeg-v4l2-request-fourier installed (link-time ABI source)
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
# Idempotent: pre-install the marfrit fourier ffmpeg so cmake
# finds libavcodec / libavformat / libavutil headers + .so's.
# Mirrors mpv-fourier-debian's [marfrit] step.
curl -sLo /tmp/marfrit.gpg https://packages.reauktion.de/marfrit.gpg
pacman-key --add /tmp/marfrit.gpg
pacman-key --lsign-key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C
rm -f /tmp/marfrit.gpg
if ! grep -q '^\[marfrit\]' /etc/pacman.conf; then
printf '\n[marfrit]\nServer = https://packages.reauktion.de/arch/$arch\nSigLevel = Required\n' >> /etc/pacman.conf
fi
pacman -Sy --noconfirm
rm -f /var/cache/pacman/pkg/ffmpeg-v4l2-request-fourier-*-aarch64.pkg.tar.*
printf 'y\ny\ny\n' | pacman -S --needed marfrit/ffmpeg-v4l2-request-fourier
- name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519_hertz
chmod 600 /root/.ssh/id_ed25519_hertz
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build daedalus-v4l2 .deb
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd debian/daedalus-v4l2
./build-deb.sh
ls -la *.deb
- name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd debian/daedalus-v4l2
DEB=$(ls daedalus-v4l2_*.deb | head -1)
retry rsync -av -e 'ssh -i /root/.ssh/id_ed25519_hertz' "$DEB" \
marfritrepo@hertz.fritz.box:
for suite in bookworm trixie; do
retry ssh -i /root/.ssh/id_ed25519_hertz marfritrepo@hertz.fritz.box \
"publish-deb $suite $DEB"
done
- name: wipe secrets
if: always()
run: rm -f /root/.ssh/id_ed25519_hertz
# -------------------------------------------------------------------------
# daedalus-v4l2-dkms Debian (Architecture: all) — packages the kernel
# source tree + dkms.conf. No compilation; just file copy + dpkg-deb.
# -------------------------------------------------------------------------
daedalus-v4l2-dkms-debian:
needs: daedalus-v4l2-debian
runs-on: arch-aarch64
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh debian/daedalus-v4l2-dkms)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: install tooling
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed dpkg openssh rsync curl tar gzip
- name: install hertz deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_HERTZ_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519_hertz
chmod 600 /root/.ssh/id_ed25519_hertz
ssh-keyscan -t ed25519 hertz.fritz.box >> /root/.ssh/known_hosts 2>/dev/null
- name: build daedalus-v4l2-dkms .deb
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd debian/daedalus-v4l2-dkms
./build-deb.sh
ls -la *.deb
- name: upload + publish to suites
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd debian/daedalus-v4l2-dkms
DEB=$(ls daedalus-v4l2-dkms_*.deb | head -1)
retry rsync -av -e 'ssh -i /root/.ssh/id_ed25519_hertz' "$DEB" \
marfritrepo@hertz.fritz.box:
for suite in bookworm trixie; do
retry ssh -i /root/.ssh/id_ed25519_hertz marfritrepo@hertz.fritz.box \
"publish-deb $suite $DEB"
done
- name: wipe secrets
if: always()
run: rm -f /root/.ssh/id_ed25519_hertz
# -------------------------------------------------------------------------
# mesa-panvk-bifrost (aarch64 only) — patched Mesa libvulkan_panfrost.so
# for Bifrost-gen Mali (panvk-bifrost campaign iter9). Co-installs at
# /usr/lib/panvk-bifrost/ so stock mesa stays intact; opt-in via the
# brave-vulkan launcher this package also ships.
#
# Build is slow (~30-60min on actrunner-aarch64): full Mesa-from-source.
# Standalone job — no `needs:` since it doesn't depend on the fourier
# codec stack. continue-on-error so a build hiccup doesn't block other
# jobs in the same workflow run.
# -------------------------------------------------------------------------
mesa-panvk-bifrost-aarch64:
runs-on: arch-aarch64
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: skip if already published
id: skip-check
run: |
set -e
result=$(./.gitea/scripts/check-already-published.sh arch/mesa-panvk-bifrost)
echo "$result" >> "$GITHUB_OUTPUT"
echo "decision: $result"
- name: bootstrap runner (idempotent)
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
retry pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo
- name: import signing key
if: steps.skip-check.outputs.skip != '1'
env:
PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }}
PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }}
run: |
set -e
gpgconf --homedir /root/.gnupg --kill all 2>/dev/null || true
rm -rf /root/.gnupg /root/repo_pass
mkdir -m700 -p /root/.gnupg
printf '%s' "$PASS" > /root/repo_pass
chmod 600 /root/repo_pass
printf '%s\n' "$PRIV" | gpg --batch --import
echo "92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C:6:" | gpg --import-ownertrust
- name: install deploy ssh key
if: steps.skip-check.outputs.skip != '1'
env:
KEY: ${{ secrets.MARFRIT_REPO_DEPLOY_KEY }}
run: |
mkdir -m700 -p /root/.ssh
printf '%s\n' "$KEY" > /root/.ssh/id_ed25519
chmod 600 /root/.ssh/id_ed25519
ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null
- name: makepkg mesa-panvk-bifrost
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
rm -rf /tmp/build-mesa-panvk-bifrost
cp -r arch/mesa-panvk-bifrost /tmp/build-mesa-panvk-bifrost
chown -R builder:builder /tmp/build-mesa-panvk-bifrost
cd /tmp/build-mesa-panvk-bifrost
# MAKEFLAGS for parallel build; runner is multi-core.
# --skipinteg because sha256sums=SKIP in PKGBUILD (matches the
# fourier-fork PKGBUILD convention).
sudo -u builder -H env MAKEFLAGS="-j60" \
makepkg --nocheck --noconfirm --syncdeps --cleanbuild --skipinteg
ls -la *.pkg.tar.* | grep -v "\.sig$"
- name: sign mesa-panvk-bifrost
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
cd /tmp/build-mesa-panvk-bifrost
for f in *.pkg.tar.xz *.pkg.tar.zst *.pkg.tar.gz; do
[ -f "$f" ] || continue
gpg --batch --pinentry-mode loopback --passphrase-file /root/repo_pass \
--detach-sign --yes -u 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C "$f"
done
- name: update aarch64 repo db
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
mkdir -p /tmp/arch-stage-mesa-panvk
cd /tmp/arch-stage-mesa-panvk
rm -f *
for f in marfrit.db.tar.gz marfrit.db.tar.gz.sig marfrit.files.tar.gz marfrit.files.tar.gz.sig; do
curl -sSLf "https://packages.reauktion.de/arch/aarch64/$f" -o "$f" || rm -f "$f"
done
for ext in xz zst gz; do
ls /tmp/build-mesa-panvk-bifrost/*.pkg.tar.$ext 2>/dev/null && \
mv /tmp/build-mesa-panvk-bifrost/*.pkg.tar.$ext /tmp/build-mesa-panvk-bifrost/*.pkg.tar.$ext.sig .
done || true
export GNUPGHOME=/root/.gnupg
printf 'pinentry-mode loopback\npassphrase-file /root/repo_pass\n' > /root/.gnupg/gpg.conf
printf 'allow-loopback-pinentry\n' > /root/.gnupg/gpg-agent.conf
gpg-connect-agent reloadagent /bye
pkgs=()
for ext in xz zst gz; do
for f in *.pkg.tar.$ext; do [ -f "$f" ] && pkgs+=("$f"); done
done
if [ -f marfrit.db.tar.gz ]; then
for f in "${pkgs[@]}"; do
name=$(echo "$f" | sed -E 's/-[0-9].*//')
repo-remove --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
marfrit.db.tar.gz "$name" 2>/dev/null || true
done
fi
repo-add --new --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \
--verify marfrit.db.tar.gz "${pkgs[@]}"
ln -sf marfrit.db.tar.gz marfrit.db
ln -sf marfrit.files.tar.gz marfrit.files
ln -sf marfrit.db.tar.gz.sig marfrit.db.sig
rm -f marfrit.files.sig
- name: publish to aarch64
if: steps.skip-check.outputs.skip != '1'
run: |
set -e
retry() { for i in 1 2 3; do "$@" && return 0; rc=$?; echo "retry $i (exit=$rc)" >&2; sleep $((i*5)); done; return 1; }
cd /tmp/arch-stage-mesa-panvk
retry rsync -avL --copy-unsafe-links \
-e 'ssh -i /root/.ssh/id_ed25519' \
./ mfritsche@nc.reauktion.de:arch/aarch64/
- name: wipe secrets
if: always()
run: rm -f /root/repo_pass /root/.ssh/id_ed25519