From 6f3490dd3616e6b405e22fe89793cb5ffb89d489 Mon Sep 17 00:00:00 2001 From: npub1t2tgm7d8f995uqvmnm8h88sg3wnpp9a5xysjf6dg3tjmgt3ltulqdp8ehr <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@buzz.block.builderlab.xyz> Date: Sat, 1 Aug 2026 23:15:13 -0400 Subject: [PATCH] build: add Sprig agent image Co-authored-by: npub1t2tgm7d8f995uqvmnm8h88sg3wnpp9a5xysjf6dg3tjmgt3ltulqdp8ehr <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@buzz.block.builderlab.xyz> Signed-off-by: npub1t2tgm7d8f995uqvmnm8h88sg3wnpp9a5xysjf6dg3tjmgt3ltulqdp8ehr <5a968df9a7494b4e019b9ecf739e088ba61097b4312124e9a88ae5b42e3f5f3e@buzz.block.builderlab.xyz> --- Dockerfile.sprig | 44 +++++++++++++++++++++++++++++++++++++ scripts/sprig-entrypoint.sh | 16 ++++++++++++++ scripts/test-sprig-image.sh | 43 ++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 Dockerfile.sprig create mode 100755 scripts/sprig-entrypoint.sh create mode 100755 scripts/test-sprig-image.sh diff --git a/Dockerfile.sprig b/Dockerfile.sprig new file mode 100644 index 000000000..583c1ae3f --- /dev/null +++ b/Dockerfile.sprig @@ -0,0 +1,44 @@ +# syntax=docker/dockerfile:1.7 +# Multi-arch is produced by building this file on native amd64 and arm64 runners. +# Keep both bases pinned to manifest-list digests so either architecture resolves +# to immutable source bytes. +FROM rust:1.95-alpine3.22@sha256:064dfc925d68d1a63f4fd2871bd7dc6e6ea56692989a487185855d62885d90aa AS builder + +RUN apk add --no-cache \ + build-base \ + cmake \ + git \ + musl-dev \ + openssl-dev \ + openssl-libs-static \ + perl \ + pkgconf \ + protoc +WORKDIR /build +COPY . . +RUN cargo build --locked --profile sprig -p sprig \ + && strip target/sprig/sprig + +FROM alpine:3.22@sha256:14358309a308569c32bdc37e2e0e9694be33a9d99e68afb0f5ff33cc1f695dce + +RUN apk add --no-cache bash ca-certificates git \ + && adduser -D -h /home/agent agent \ + && install -d -o agent -g agent /workspace /home/agent \ + && git config --system gpg.format x509 \ + && git config --system gpg.x509.program /usr/local/bin/git-sign-nostr \ + && git config --system commit.gpgSign true \ + && git config --system tag.gpgSign true + +COPY --from=builder --chmod=0755 /build/target/sprig/sprig /usr/local/bin/sprig +COPY --chmod=0755 scripts/sprig-entrypoint.sh /usr/local/bin/sprig-entrypoint +RUN for name in \ + buzz-acp buzz-agent buzz-dev-mcp rg tree buzz \ + git-credential-nostr git-sign-nostr; do \ + ln -s sprig "/usr/local/bin/$name"; \ + done + +ENV HOME=/home/agent \ + PATH=/usr/local/bin:/usr/local/sbin:/usr/sbin:/usr/bin:/sbin:/bin +WORKDIR /home/agent +USER agent +ENTRYPOINT ["/usr/local/bin/sprig-entrypoint"] diff --git a/scripts/sprig-entrypoint.sh b/scripts/sprig-entrypoint.sh new file mode 100755 index 000000000..16abf7bc5 --- /dev/null +++ b/scripts/sprig-entrypoint.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -euo pipefail + +# Match desktop's URL-scoped git credential configuration without installing a +# helper globally (which would make it answer for unrelated remotes). +if [[ -n "${BUZZ_RELAY_URL:-}" ]]; then + relay_http_url="${BUZZ_RELAY_URL/#ws:/http:}" + relay_http_url="${relay_http_url/#wss:/https:}" + relay_http_url="${relay_http_url%/}" + git config --global "credential.${relay_http_url}/git.helper" \ + /usr/local/bin/git-credential-nostr + git config --global "credential.${relay_http_url}/git.useHttpPath" true +fi + +# The harness must receive Kubernetes' termination signal directly. +exec buzz-acp "$@" diff --git a/scripts/test-sprig-image.sh b/scripts/test-sprig-image.sh new file mode 100755 index 000000000..4ca42fdb4 --- /dev/null +++ b/scripts/test-sprig-image.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +set -euo pipefail + +IMAGE="${1:-buzz-sprig:contract-test}" +if [[ "${SKIP_BUILD:-0}" != 1 ]]; then + docker build --file Dockerfile.sprig --tag "$IMAGE" . +fi + +assert_run() { + docker run --rm --entrypoint /bin/bash "$IMAGE" -ceu "$1" +} + +assert_run ' + command -v bash git update-ca-certificates >/dev/null + test "$(readlink /usr/local/bin/buzz-acp)" = sprig + for name in buzz-agent buzz-dev-mcp rg tree buzz git-credential-nostr git-sign-nostr; do + test "$(readlink "/usr/local/bin/$name")" = sprig + done + test "$(git config --system gpg.x509.program)" = /usr/local/bin/git-sign-nostr + ! git config --system --get-all credential.helper + test "$HOME" = /home/agent + test "$(pwd)" = /home/agent +' + +assert_run ' + grep -Eq "^[[:space:]]*exec buzz-acp" /usr/local/bin/sprig-entrypoint + ! grep -Eq "^[[:space:]]*(buzz-acp|bash -c .*buzz-acp)" /usr/local/bin/sprig-entrypoint +' + +docker run --rm --entrypoint /bin/bash \ + -e BUZZ_RELAY_URL=wss://relay.example.test/ "$IMAGE" -ceu ' + /usr/local/bin/sprig-entrypoint --help >/dev/null 2>&1 & pid=$! + for _ in 1 2 3 4 5; do + git config --global --get credential.https://relay.example.test/git.helper >/dev/null 2>&1 && break + sleep 0.1 + done + test "$(git config --global --get credential.https://relay.example.test/git.helper)" = /usr/local/bin/git-credential-nostr + test "$(git config --global --get credential.https://relay.example.test/git.useHttpPath)" = true + ! git config --global --get-all credential.helper + wait "$pid" || true + ' + +echo "PASS: Sprig image runtime contract ($IMAGE)"