ci: publish Sprout Agent Bundle (sprout-acp + sprout-agent + sprout-dev-mcp) to GitHub Releases#603
Merged
Merged
Conversation
…ev-mcp) to GitHub Releases
Adds a Linux release bundle for external services that need to embed a
Sprout agent end-to-end (e.g. sprout-backend-blox).
What's in the bundle:
- sprout-acp — ACP harness that bridges Sprout events to an agent
- sprout-agent — ACP-compliant agent (spawns MCP, calls LLMs)
- sprout-dev-mcp — Developer MCP server (multicall: rg, tree, sprout,
git-credential-nostr, git-sign-nostr)
Workflow `.github/workflows/sprout-agent-bundle.yml`:
- Targets x86_64-unknown-linux-musl and aarch64-unknown-linux-musl
- Uses the same `cross@0.2.5` toolchain already pinned in ci.yml
- Triggers:
push to main → updates rolling
`sprout-agent-bundle-latest` release
tag `sprout-agent-bundle-v*` → versioned release
workflow_dispatch → manual build (optional publish)
- Uses `gh release` (matches release.yml style), not a new third-party
action
- Uploads asset + .sha256 sidecar per target
Script `scripts/build-agent-bundle.sh` is the single source of truth for
packaging (CI calls it directly). It:
- Builds with `cross` when cross-compiling, plain `cargo` on host
- Strips binaries (best-effort)
- Emits `bundle.json` with {name, version, git_sha, target, binaries:
[{name, sha256, size}]} for downstream consumers
- Produces a deterministic-ish tarball (sorted, uid=0/gid=0) with a
README and bundle.json
- Supports SKIP_BUILD=1 for re-packaging without rebuilding (used in
local verification and useful for fast iteration)
Replaces `scripts/build-agent-release.sh`, which only packaged
sprout-agent + sprout-dev-mcp.
Not in this PR (intentional, per discussion):
- sprout-backend-blox is not yet switched over to consume the bundle
- macOS/Windows bundles
- sprout-mcp-server, git-credential-nostr, git-sign-nostr as separate
binaries (the dev-mcp multicall covers them)
Verified locally on aarch64-apple-darwin with SKIP_BUILD=1: tarball
contains the 3 binaries + README.md + bundle.json, sha256 sidecar
matches, and bundle.json parses cleanly under jq.
Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
…ble rolling asset names, single-source build Addresses Max's review on #603. Rolling release semantics: - Force-move the `sprout-agent-bundle-latest` git tag to the current `main` SHA before touching the release. `gh release edit` updates release metadata but does not move the underlying tag, so without this the tag would stick to whatever SHA first created the release. Uses `gh api PATCH .../git/refs/tags/...` (with force=true) and falls back to `POST .../git/refs` for the initial-create case. - Also pass `--target ${SHA}` to `gh release create/edit` so the release's "target commitish" tracks the build SHA. Stale-asset cleanup on the rolling release: - Rolling builds now use stable, version-less asset filenames (`sprout-agent-bundle-<target>.tar.gz`). `--clobber` overwrites them in place on every push, so the release no longer accumulates SHA-named tarballs. - Tagged releases keep the versioned filename (`sprout-agent-bundle-<version>-<target>.tar.gz`) for traceability. - The git SHA + version always live inside `bundle.json` regardless of the asset filename, so consumers/debugging never lose provenance. - `scripts/build-agent-bundle.sh` gains an `ARCHIVE_BASENAME` env var override (documented in the header) so the workflow can pick the right filename per channel; default unchanged. Single source of truth for the build: - Removed the workflow's explicit `cross build` step. The script already auto-selects `cross` when target != host, so the previous setup was building everything twice. Verified locally with `SKIP_BUILD=1`: - Rolling-style basename → `sprout-agent-bundle-<target>.tar.gz` with sha sidecar `OK` under `sha256sum -c`. - Tagged-style basename → `sprout-agent-bundle-<version>-<target>.tar.gz`. - Both tarballs contain the 3 binaries + README + bundle.json with matching shas/sizes. - actionlint + shellcheck clean. Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
…giene) Per the zizmor PR review thread on #603: the SHA-pinned action comments should match the exact upstream tag, not a broader floating tag, so the scanner doesn't flag a metadata mismatch. - taiki-e/install-action: `# v2` → `# v2.75.18` (the SHA's exact tag) - actions/upload-artifact: `# v4` → `# v4.6.2` - actions/download-artifact: `# v4` → `# v4.3.0` Pinned SHAs are unchanged — no behavior change, just correct metadata. `actions/checkout` and `cashapp/activate-hermit` already match (their SHAs are the literal `v6` / `v1` commits). Signed-off-by: Tyler Longwell <109685178+tlongwell-block@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a Linux release bundle for external services that need to embed a Sprout agent end-to-end (e.g.
sprout-backend-blox).The bundle contains the three binaries needed to run a Sprout agent:
sprout-acpsprout-agentsprout-dev-mcprg,tree,sprout,git-credential-nostr,git-sign-nostrWhat's in this PR
.github/workflows/sprout-agent-bundle.ymlx86_64-unknown-linux-muslandaarch64-unknown-linux-musl(static musl, runs on any modern Linux)cross@0.2.5toolchain already pinned inci.yml— no new toolchain dependencypushtomain→ updates rollingsprout-agent-bundle-latestprereleasesprout-agent-bundle-v*→ versioned releaseworkflow_dispatch→ manual build (optional publish via input)gh release(matches the in-repo style fromrelease.yml) rather than introducingsoftprops/action-gh-release<bundle>.tar.gz+<bundle>.tar.gz.sha256per targetscripts/build-agent-bundle.shSingle source of truth for packaging — CI calls it directly so local builds and CI builds produce byte-identical structure.
crosswhen cross-compiling, plaincargoon host (no Docker requirement for contributors)bundle.jsonwith{name, version, git_sha, target, binaries: [{name, sha256, size}]}— machine-readable manifest for downstream consumersuid=0/gid=0, numeric owner), with BSD-tar fallback for local macOS useSKIP_BUILD=1re-packages without rebuilding (used in local verification)Replaces
scripts/build-agent-release.sh, which only packaged 2 binaries..gitignoreAdds
/dist/so the bundle script's output doesn't pollute working trees.Verification
Ran locally on
aarch64-apple-darwinwithSKIP_BUILD=1:bundle.jsonparses cleanly underjq, sha256 sidecar matches,actionlintclean on the workflow.Out of scope (intentional)
sprout-backend-bloxis not switched over to consume the bundle yet — that's the follow-up PR once this lands and we have a release artifact to point at.git-credential-nostr/git-sign-nostrbinaries — thesprout-dev-mcpmulticall covers them.