feat(#5183): publish runner image with fullsend CLI and host-side run dependencies - #5201
Conversation
Site previewPreview: https://337dcacb-site.fullsend-ai.workers.dev Commit: |
PR Summary by QodoPublish fullsend-runner image with CLI and host-side run dependencies
AI Description
Diagram
High-Level Assessment
Files changed (6)
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Code Review by Qodo
Context used✅ Tickets:
🎫 Release a container image with the fullsend CLI and all host-side run dependencies pre-installed✅ Compliance rules (platform):
54 rules✅ Skills:
writing-user-docs, writing-adrs 1.
|
6d439ca to
5a408a3
Compare
|
🤖 Review · |
|
🤖 Review · |
… dependencies Publish `ghcr.io/fullsend-ai/fullsend-runner` on every version tag: a UBI 10-based image bundling the fullsend CLI (compiled from the tagged source) and every host-side dependency that `fullsend run`'s pre-scripts, validation loop, and post-scripts invoke — so local runs get the same environment the composite action assembles in CI instead of failing on missing dependencies. Podman, the openshell-gateway, and the supervisor image stay on the host; the containerized CLI reaches the gateway over the network and sandboxes still spawn on the host. ## Changes - `images/runner/Containerfile` — multi-stage build: build stage on `ubi10/go-toolset` cross-compiles fullsend with the same ldflags as GoReleaser; runtime stage on plain `ubi10/ubi` with: OpenShell CLI pinned via `.github/scripts/openshell-version.sh`, gh, gitleaks, pre-commit + gitlint, python3 + jsonschema (pinned ==4.23.0, matching the sandbox image), Go, git, jq, tar. gcloud included for the local-run guide's GCP credential bootstrap. All third-party downloads version-pinned and SHA256-verified. Base images digest-pinned. Final size ~1.1 GB. Runs as root (local convenience wrapper, not a sandbox; rootless podman maps container root to the invoking host user). - `.github/workflows/runner-image.yml` — smoke-test (single-platform load + full dependency-surface validation) runs BEFORE the multi-arch build-and-push, so a broken image never reaches the registry. Tags linux/amd64 + linux/arm64 on version tags and on `images/runner/` changes. Tag trigger aligned with release.yml (three-component semver). `:dev` tag scoped to `refs/heads/main` only so release builds never move it onto a release image. No `latest` from main — `latest` always points at the newest release. - `renovate.json` — custom manager tracking `GCLOUD_VERSION` against `gcr.io/google.com/cloudsdktool/google-cloud-cli` tags (semver versioning constraint); SHA256 args refreshed manually. - `docs/guides/user/running-agents-locally.md` — new section on running the CLI from the container image: mounts (including `/tmp/fullsend` for run artifacts), corrected gcloud auth flow (remote-bootstrap two-machine flow, not URL+code), macOS noted as untested with candidate path via `host.containers.internal`, SELinux `:z` guidance, sandbox-log diagnostics note. OpenShell prerequisite updated to 0.0.83. - `images/README.md` — runner image section (explicitly not a sandbox image), supply-chain table rows with OpenShell trust-model note. - `.dockerignore` — trims the repo-root build context; excludes credential/key file patterns as defense in depth. Assisted-by: Claude (fix), Claude (review), Grok (review) Signed-off-by: Wayne Sun <gsun@redhat.com>
5a408a3 to
6f3691e
Compare
|
🤖 Finished Review · ✅ Success · Started 4:06 PM UTC · Completed 4:13 PM UTC |
ReviewFindingsMedium
Low
Previous runReviewFindingsMedium
Low
Labels: PR adds a new runner image (images/runner/), CI workflow (.github/workflows/), and documentation (docs/guides/). Previous run (2)ReviewFindingsMedium
Low
Previous runReview — approvePR: #5201 — SummaryThis PR introduces a new Correctness
Security
Intent & Coherence
Style & Conventions
Documentation
Renovate Integration
No findings at low severity or above.
Previous run (3)ReviewFindingsMedium
Low
Previous run (4)Review — approvePR: #5201 — SummaryThis PR introduces a new Correctness
Security
Intent & Coherence
Style & Conventions
Documentation
Renovate Integration
No findings at low severity or above.
|
|
🤖 Finished Review · ✅ Success · Started 5:34 PM UTC · Completed 5:49 PM UTC |
The OpenShell version pin in .github/scripts/openshell-version.sh is bumped automatically by Renovate. Hardcoding the version in the prerequisites table and install section goes stale on every bump. - Prerequisites table: link to the pin file instead of hardcoding - Install section: note that Renovate manages the version and the snippet is an example — check the pin file at your release tag Signed-off-by: Wayne Sun <gsun@redhat.com> Assisted-by: Claude
109bdf3 to
1ebd38a
Compare
|
🤖 Finished Review · ✅ Success · Started 9:47 PM UTC · Completed 9:57 PM UTC |
Move the container alternative section after the native run examples instead of before them, trim it down to remove content already implied by context (openshell-gateway definition, image pinning, gcloud-in-container auth flow), and relocate platform-specific caveats to their proper sections (macOS limitation to platform notes, GCP key mounting to the credentials section) with forward links so readers aren't confused by early references. Assisted-by: Claude Signed-off-by: Wayne Sun <gsun@redhat.com>
|
🤖 Review · |
Built the runner image locally and ran fullsend run triage against it on macOS to verify the existing caution note. Two issues confirmed: - Bind-mounting /tmp/... paths fails outright (statfs: no such file or directory) — Podman Desktop's VM shares /Users, /private, and /var/folders via virtiofs but not the /tmp symlink target. - With mounts fixed via /private/tmp/..., sandbox creation still fails with connection-refused: --network=host reaches the Podman VM's loopback, not the macOS host, and the gateway binds to 127.0.0.1 only so host.containers.internal doesn't help either. Replace the "untested, try it" framing with the confirmed failure modes so macOS readers aren't invited to debug a known dead end. Assisted-by: Claude Signed-off-by: Wayne Sun <gsun@redhat.com>
|
🤖 Review · |
Every reference to the container alternative now says "Linux only" (or links to a header that does) before the reader clicks through, and the macOS bail-out note moved to the first line of its section instead of after two paragraphs of Linux-only setup instructions. Previously a macOS reader had to read through the section pitch, prerequisites, and part of the mount example before learning it doesn't apply to them. Assisted-by: Claude Signed-off-by: Wayne Sun <gsun@redhat.com>
Built and served the actual VitePress site locally to check the rendered
page. The "On this page" outline panel is a fixed 207px box with
text-overflow: ellipsis on a single line — the previous heading
("Alternative: run the CLI from the container image (Linux only)", 390px
wide) truncated well before the "(Linux only)" qualifier, which defeated
the point of adding it. Shortened to "Run from a container (Linux)"
(207px, exact fit, confirmed via scrollWidth == offsetWidth) so a macOS
reader scanning the outline sees the platform scope without opening the
section. Verified anchor links still resolve to the right heading and
land on the macOS bail-out line first.
Assisted-by: Claude
Signed-off-by: Wayne Sun <gsun@redhat.com>
|
🤖 Finished Review · ✅ Success · Started 2:47 PM UTC · Completed 3:05 PM UTC |
|
|
||
| ```bash | ||
| export OPENSHELL_VERSION=0.0.72 | ||
| export OPENSHELL_VERSION=0.0.83 # check the pin file for the current version |
There was a problem hiding this comment.
[low] version-drift
The install example hardcodes OPENSHELL_VERSION=0.0.83 with a comment directing users to the pin file. This hardcoded value will silently drift out of sync with .github/scripts/openshell-version.sh as future releases bump the pin. The prerequisites table correctly links to the pin file rather than hardcoding.
Suggested fix: Consider adding a Renovate custom manager or CI lint that keeps this example version in sync with the pin file.
| @@ -1,8 +1,10 @@ | |||
| # Sandbox Images | |||
| # Images | |||
There was a problem hiding this comment.
[low] heading-capitalization
The heading changed from '# Sandbox Images' to '# Images'. While the PR updates the intro paragraph to mention the runner image, the first sentence still leads with sandbox-centric language.
|
🤖 Finished Retro · ✅ Success · Started 3:08 PM UTC · Completed 3:30 PM UTC |
Retro: PR #5201 — Runner image with fullsend CLIPR #5201 published a new runner container image ( Key finding: complete disjointness between AI and human reviewThe review agent found 7 items (1 medium protected-path flag, 6 low: supply-chain circular checksum, version drift, ENV placement, heading mismatch, smoke-test style). The human reviewer found 8 items — all about documentation information architecture in the user guide: sections placed too early referencing unexplained concepts, verbose explanations where concise ones suffice, overly complex credential alternatives, and an untested macOS container workflow. Zero findings overlapped. The most impactful finding was the human’s challenge “Weren’t you running on macOS? Could you test this?” — which revealed the documented macOS container path was completely broken (two distinct bugs: bind-mount symlink resolution failure and network isolation to VM loopback). Proposal filed
Evidence for existing issues
Autonomy observationsThe review agent performed well on Containerfile and CI workflow dimensions — supply-chain verification, version pinning, and style findings were all appropriate and uncontested by the human reviewer. The human focused exclusively on the user-facing documentation guide and did not comment on infrastructure files. This is complementary coverage, not redundancy. However, the documentation quality gap means human review remains essential for PRs adding substantial new user-facing documentation. Proposals filed
|
Summary
Publish
ghcr.io/fullsend-ai/fullsend-runneron every version tag: a UBI 10-based image bundling the fullsend CLI (compiled from the tagged source) and every host-side dependency thatfullsend run's pre-scripts, validation loop, and post-scripts invoke — so local runs get the same environment the composite action assembles in CI instead of failing on missing dependencies. Podman, the openshell-gateway, and the supervisor image stay on the host; the containerized CLI reaches the gateway over the network and sandboxes still spawn on the host.Related Issue
Closes #5183
Changes
images/runner/Containerfile— multi-stage build:ubi10/go-toolset(anonymous pull from registry.access.redhat.com) cross-compiles fullsend with the same ldflags as GoReleaser, sofullsend --versionreports the release version.ubi10/ubi(deliberately not go-toolset, which carries gcc/build deps and adds ~600 MB) with: OpenShell CLI pinned via.github/scripts/openshell-version.sh(extracted at build time, so Renovate's existing pin bumps flow through automatically), gh, gitleaks, pre-commit + gitlint, python3 + jsonschema, Go, git, jq, tar.images/sandboxandimages/codewhere shared; base images digest-pinned..github/workflows/runner-image.yml— builds and pushes linux/amd64 + linux/arm64 on version tags and onimages/runner/changes; smoke-tests the full dependency surface on a loaded single-platform build. Nolatestfrom main pushes —latestalways points at the newest release.renovate.json— custom manager trackingGCLOUD_VERSIONagainstgcr.io/google.com/cloudsdktool/google-cloud-clitags. The SHA256 args are refreshed manually; a stale-hash bump PR fails the runner-image PR build's checksum verification, which blocks automerge.docs/guides/user/running-agents-locally.md— new section on running the CLI from the container: mounts,--network=hostgateway access on Linux, macOS limitation, and the gcloud auth flow in a browserless container (gcloud auth login --no-launch-browser, persisting~/.config/gcloudvia mount).images/README.md— runner image section (explicitly not a sandbox image) and supply-chain table rows..dockerignore— trims the repo-root build context.Testing
make lintpasses (stage changes first, then run)podman buildof the image plus the same smoke test the workflow runs: all checks pass — fullsend reports the injected version, openshell 0.0.83 (matching the pin), gh 2.96.0, gitleaks 8.30.1, pre-commit 4.5.1, gitlint 0.19.1, jsonschema import, Go 1.26.0, Google Cloud SDK 576.0.0, git/jq/tar presentChecklist
!for breaking changes)