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//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: debian-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; } export DEBIAN_FRONTEND=noninteractive retry apt-get update -qq # Debian build-deps for the FFmpeg fourier-fork build. These # map 1:1 to the previous Arch list; libav*-dev intentionally # absent (we are FFmpeg itself, providing those libs). retry apt-get install -y --no-install-recommends \ build-essential git pkg-config nasm yasm \ linux-libc-dev libgl1-mesa-dev libasound2-dev libbz2-dev \ libfontconfig-dev libfribidi-dev libgmp-dev libgnutls28-dev \ libmp3lame-dev libass-dev libdav1d-dev libdrm-dev \ libfreetype-dev libpulse-dev libva-dev libvorbis-dev libvpx-dev \ libwebp-dev libx264-dev libx265-dev libxml2-dev libopus-dev \ v4l-utils liblzma-dev zlib1g-dev \ curl ca-certificates openssh-client rsync 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 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_ # at compile time from . 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 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: debian-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; } export DEBIAN_FRONTEND=noninteractive retry apt-get update -qq # Debian libav*-dev is ABI-compatible with the fourier ffmpeg # fork at the header level; mpv link-binds against system # libav at build time, runtime dlopen picks up the fourier # libs if installed. The previous [marfrit] pre-install of # ffmpeg-v4l2-request-fourier under pacman is unnecessary # under apt: stock Debian libav*-dev provides the trixie # ABI mpv-fourier's binary will encounter. retry apt-get install -y --no-install-recommends \ build-essential git meson ninja-build pkg-config python3-docutils \ ladspa-sdk wayland-protocols libvulkan-dev libwayland-dev \ libasound2-dev desktop-file-utils libc6-dev hicolor-icon-theme \ libjack-jackd2-dev liblcms2-dev libarchive-dev libass-dev \ libbluray-dev libcdio-dev libcdio-paranoia-dev libdisplay-info-dev \ libdrm-dev libdvdnav-dev libdvdread-dev libegl-dev libgl-dev \ libglvnd-dev libjpeg-dev libplacebo-dev libpulse-dev libsixel-dev \ libva-dev libvdpau-dev libx11-dev libxext-dev libxkbcommon-dev \ libxpresent-dev libxrandr-dev libxss-dev libxv-dev libluajit-5.1-dev \ libmujs-dev libpipewire-0.3-dev librubberband-dev libsdl2-dev \ libopenal-dev libuchardet-dev libvapoursynth-dev liblzma-dev \ libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev \ zlib1g-dev \ curl ca-certificates openssh-client rsync 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 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: debian-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 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 # libav*-dev provide the headers daedalus daemon dlopens at # runtime — Debian's stock packages match the trixie ABI the # daemon will encounter on Pi 5 hosts (both ship libavcodec # 61.x). The fourier ffmpeg fork isn't needed here; the # daemon never link-binds against libav (Option γ — dlopen # at runtime), so any header set with the right struct # definitions works. # libvulkan-dev + glslang-tools: needed by the in-build # daedalus-fourier fetch (build-deb.sh fetches the sibling # library, cmake-builds it into a temp prefix, then the # daedalus daemon static-links against it via pkg-config). # Without these, daedalus-fourier's find_package(Vulkan) # and glslangValidator find_program both fail at configure # time. See marfrit/daedalus-fourier PR #1 + # reauktion/daedalus-v4l2 PR #13. retry apt-get install -y --no-install-recommends \ build-essential cmake ninja-build pkg-config git \ libavcodec-dev libavformat-dev libavutil-dev libdrm-dev \ libvulkan-dev glslang-tools \ linux-libc-dev \ curl ca-certificates openssh-client rsync 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 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: debian-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; } export DEBIAN_FRONTEND=noninteractive retry apt-get update -qq retry apt-get install -y --no-install-recommends \ dpkg-dev openssh-client rsync curl ca-certificates 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