diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index c2ec85b7c..fa2eb39af 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -5,20 +5,18 @@ on: branches: [main] paths: - 'arch/**' - - '.gitea/workflows/build.yml' + - 'debian/**' + - '.gitea/workflows/**' workflow_dispatch: jobs: distcc-avahi-aarch64: runs-on: arch-aarch64 steps: - - name: checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - name: install builder deps (idempotent) + - name: bootstrap runner (idempotent) run: | - # runner image is Arch aarch64 with base-devel + gnupg + rsync + sudo. - # This step exists so a freshly re-imaged runner bootstraps itself. pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo avahi popt python python-setuptools - name: import signing key @@ -27,8 +25,6 @@ jobs: PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }} run: | set -e - # Runner container persists between runs; wipe any stale gpg state - # so old gpg.conf / socket paths can't confuse this build. rm -rf /root/.gnupg /root/repo_pass mkdir -m700 -p /root/.gnupg printf '%s' "$PASS" > /root/repo_pass @@ -45,12 +41,9 @@ jobs: chmod 600 /root/.ssh/id_ed25519 ssh-keyscan -t ed25519 nc.reauktion.de > /root/.ssh/known_hosts 2>/dev/null - - name: makepkg + - name: makepkg distcc-avahi run: | set -e - # act's workspace lives under /root/.cache/act which the unprivileged - # 'builder' user can't write to. Copy the package source into a - # builder-owned /tmp dir. rm -rf /tmp/build-distcc-avahi cp -r arch/distcc-avahi /tmp/build-distcc-avahi chown -R builder:builder /tmp/build-distcc-avahi @@ -58,7 +51,7 @@ jobs: sudo -u builder -H makepkg --nocheck --noconfirm --syncdeps --cleanbuild ls -la *.pkg.tar.* | grep -v "\.sig$" - - name: sign package + - name: sign distcc-avahi run: | set -e cd /tmp/build-distcc-avahi @@ -67,48 +60,37 @@ jobs: gpg --batch --pinentry-mode loopback --passphrase-file /root/repo_pass \ --detach-sign --yes -u 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C "$f" done - ls -la *.sig - - name: fetch current repo db and rebuild + - name: update aarch64 repo db run: | set -e mkdir -p /tmp/arch-stage cd /tmp/arch-stage - # pull current db (may be empty skeleton on first run) + rm -f * curl -sSL https://packages.reauktion.de/arch/aarch64/marfrit.db.tar.gz -o marfrit.db.tar.gz || true curl -sSL https://packages.reauktion.de/arch/aarch64/marfrit.files.tar.gz -o marfrit.files.tar.gz || true - # move freshly built package(s) in 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 - # regenerate the db, signing it with our key - export GPG_TTY="" export GNUPGHOME=/root/.gnupg - # repo-add wants explicit passphrase; wrap via gpg-agent loopback 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 - # exclude .sig files from repo-add's positional args pkgs=() for ext in xz zst gz; do for f in *.pkg.tar.$ext; do [ -f "$f" ] && pkgs+=("$f"); done done - echo "packages to add: ${pkgs[*]}" repo-add --new --sign --key 92D5E96D8F63C75E4116AA1FF5C8C4603D0D250C \ --verify marfrit.db.tar.gz "${pkgs[@]}" - # refresh "unversioned" symlinks expected by pacman - 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.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 - ls -la - - name: publish via rrsync + - name: publish to aarch64 run: | - set -e cd /tmp/arch-stage - # rrsync on nc is scoped to /srv/packages/; target path is relative. rsync -avL --copy-unsafe-links \ -e 'ssh -i /root/.ssh/id_ed25519' \ ./ mfritsche@nc.reauktion.de:arch/aarch64/ @@ -117,10 +99,91 @@ jobs: if: always() run: rm -f /root/repo_pass /root/.ssh/id_ed25519 - # x86_64 job will mirror this one and run on the pve4 runner. - # Kept commented out until a package actually targets x86_64 — - # no point spinning pve4 for a no-op. - # - # distcc-avahi-x86_64: - # runs-on: arch-x86_64 - # steps: (same as above, with arch/x86_64/ target) + # ------------------------------------------------------------------------- + # 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: + runs-on: arch-aarch64 + steps: + - uses: actions/checkout@v4 + + - name: bootstrap runner (idempotent) + run: pacman -Syu --noconfirm --needed base-devel git rsync gnupg openssh sudo lua lua-socket + + - name: import signing key + env: + PRIV: ${{ secrets.MARFRIT_REPO_PRIVATE_KEY }} + PASS: ${{ secrets.MARFRIT_REPO_PASSPHRASE }} + run: | + set -e + 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 + 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 + 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 + 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 + run: | + set -e + 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" + curl -sSL "https://packages.reauktion.de/arch/$target/marfrit.db.tar.gz" -o marfrit.db.tar.gz || true + curl -sSL "https://packages.reauktion.de/arch/$target/marfrit.files.tar.gz" -o marfrit.files.tar.gz || true + 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 + 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 + 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 diff --git a/arch/lmcp/PKGBUILD b/arch/lmcp/PKGBUILD new file mode 100644 index 000000000..0ad8aac21 --- /dev/null +++ b/arch/lmcp/PKGBUILD @@ -0,0 +1,23 @@ +# Maintainer: Markus Fritsche +# Lightweight MCP server in pure Lua. +# Source of truth: git.reauktion.de/marfrit/lmcp + +pkgname=lmcp +pkgver=0.3.0 +pkgrel=1 +pkgdesc="Lightweight MCP (Model Context Protocol) server in pure Lua" +arch=('any') +url="https://git.reauktion.de/marfrit/lmcp" +license=('MIT') +depends=('lua' 'lua-socket') +source=("${pkgname}-${pkgver}.tar.gz::https://git.reauktion.de/marfrit/lmcp/archive/v${pkgver}.tar.gz") +sha256sums=('80a37fc41633ae285b86f2f6cdd97f0c922c03022dce09addd47aeb379f2bcff') + +package() { + cd "${pkgname}" + install -Dm644 lmcp.lua "${pkgdir}/usr/share/lua/5.4/lmcp.lua" + install -Dm644 json.lua "${pkgdir}/usr/share/lua/5.4/json.lua" + install -Dm644 server.lua "${pkgdir}/usr/share/lua/5.4/server.lua" + install -Dm755 example_server.lua "${pkgdir}/usr/bin/lmcp-example" + install -Dm644 README.md "${pkgdir}/usr/share/doc/${pkgname}/README.md" +}