Skip to content
 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

88 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sendbuilds

Build automation CLI with step events, caching, auto-detection, metrics, sandbox controls, artifact signing, and multi-target outputs.

Supported Language/Frameworks

  • Next.js, Rails, Django, Flask, Spring (Maven/Gradle), Laravel, plus generic toolchain detection by language.
  • Node.js, Python, Ruby, Go, Java, PHP, Rust, Static Sites, Shell Scripts, C/C++, Gleam, Elixir, Deno, and .NET.

Run

sendbuilds build --config sendbuild.toml

Unused dependency detection (best-effort, per language):

sendbuilds build --unused-deps

Workspace / Monorepo

sendbuilds can detect and build workspaces (Node, Rust, Go, Gradle/Maven, .NET, Python). Workspace mode is opt-in via config or CLI flags; single-project behavior is unchanged.

CLI examples:

sendbuilds build --workspace --affected
sendbuilds build --workspace --packages api,web
sendbuilds deploy --local --workspace --all

Config example:

[workspace]
enabled = true
root = "."
mode = "auto" # or "explicit"
packages = ["service-a", "service-b"]
build = "affected"

[[package]]
name = "service-a"
path = "packages/service-a"
language = "nodejs"
build_cmd = "pnpm run build"
output_dir = "dist"
targets = ["directory", "container_image"]
container_image = "service-a:latest"

Install

curl -fsSL https://sendara.cloud/sendbuilds/install.sh | bash

Install from Releases

Release assets are packaged for direct CLI install:

  • Linux/macOS: .tar.gz (contains sendbuilds + install.sh)
  • Windows: .zip (contains sendbuilds.exe + install.ps1)

Linux/macOS:

tar -xzf sendbuilds-linux-x86_64.tar.gz
./install.sh
sendbuilds --help

Windows PowerShell:

Expand-Archive .\sendbuilds-windows-x86_64.zip -DestinationPath .\sendbuilds
.\sendbuilds\install.ps1
sendbuilds.exe --help

Windows note:

  • sendbuilds.exe is a CLI, so double-clicking it in Explorer opens/closes quickly by design.
  • Run it from Terminal/PowerShell (sendbuilds.exe --help).

Local development and testing

Build and run the CLI locally:

cargo build --release
./target/release/sendbuilds --help
./target/release/sendbuilds build --config sendbuild.toml

On Windows PowerShell:

cargo build --release
.\target\release\sendbuilds.exe --help
.\target\release\sendbuilds.exe build --config sendbuild.toml

Run without a release build:

cargo run -- build --config sendbuild.toml

Localhost testing flow for a web app:

  1. Build with sendbuilds (build command).
  2. Enter the produced artifact folder under deploy.artifact_dir.
  3. Start your framework runtime from that artifact (for example pnpm run start, python manage.py runserver, etc.).

If [source] is omitted in sendbuild.toml, sendbuilds uses the current workspace as source input.

CLI commands

sendbuilds build [--config sendbuild.toml] [--events true|false]
sendbuilds build [--config sendbuild.toml] [--in-place] [--events true|false]
sendbuilds build [--config sendbuild.toml] [--reproducible]
sendbuilds build [--config sendbuild.toml] [--image <tag>] [--push-image <tag>] [--verify-image <tag>] [--push] [--backend <docker|podman|buildah|buildkit>] [--target <directory|tarball|serverless|kubernetes|container_image>]
sendbuilds build --git <repo> --docker [--branch <name>] [--image <tag>] [--push-image <tag>] [--verify-image <tag>] [--push] [--backend <docker|podman|buildah|buildkit>] [--target <directory|tarball|serverless|kubernetes|container_image>]
sendbuilds deploy [<owner/repo|git-url>] [--local] [--build] [--branch <name>] [--docker] [--target <kubernetes|serverless|tarball|directory|container_image>] [--image <tag>] [--dry-run] [--remote]
sendbuilds debug <build-id> [--config sendbuild.toml]
sendbuilds replay [<build-id>] [--buildid <build-id>] [--time-machine <date>] [--config sendbuild.toml]
sendbuilds rollback [<build-id>] [--to <date>] [--config sendbuild.toml]
sendbuilds artifacts list [--all] [--limit <n>] [--config sendbuild.toml]
sendbuilds artifacts prune [--keep-last <n>] [--max-age <days>] [--config sendbuild.toml]
sendbuilds artifacts download <artifact> [--out <path>] [--config sendbuild.toml]
sendbuilds init [--template <framework>] [--yes]
sendbuilds cache save|restore|clear|status [--config sendbuild.toml]
sendbuilds clean [--all] [--cache-only] [--config sendbuild.toml]
sendbuilds info [--env] [--dependencies] [--config sendbuild.toml]
sendbuilds rebase [--config sendbuild.toml] [--base <image>] [--image <tag>] [--from-image <tag-or-id>]
sendbuilds rebase --git [--repo <git-url>] [--branch <name>] [--base <image>] [--image <tag>]

Use --in-place to build directly in the current workspace instead of a temp copy (useful for Next.js pnpm start expecting .next in project root). If sendbuild.toml is missing, sendbuilds build automatically falls back to a smart local mode with inferred defaults and in-place build. For zero-config enterprise mode, use sendbuilds build --git <repo> --docker: it auto-generates runtime config, enables security-first checks, auto-generates a local signing key if missing, signs artifacts, emits SBOM/supply-chain metadata, and builds container images even when no Dockerfile exists. When container_image is requested, sendbuilds now treats container publish as required output: it must resolve a backend, build the image, and if push is enabled, push plus verify the registry manifest, or fail the command. Container backend selection order is: explicit --backend/container_backend, then docker, podman, buildah, and buildkit. Default storage paths are OS-aware under a sendbuilds data root:

  • Windows: %LOCALAPPDATA%/sendbuilds
  • macOS: ~/Library/Application Support/sendbuilds
  • Linux: $XDG_DATA_HOME/sendbuilds (or ~/.local/share/sendbuilds) Artifacts default to <data-root>/artifacts and cache defaults to <data-root>/cache. Within those defaults, sendbuilds auto-namespaces by a stable project storage key (project-name + repo/path fingerprint) so duplicate repo names do not collide. Accepted repo formats include:
  • owner/repo (for example notsliver/sendara-landing)
  • https://github.com/owner/repo
  • https://github.com/owner/repo.git

Build Any Repo In One Command

sendbuilds deploy owner/repo

This is a one-command wrapper around the full build+deploy pipeline (clone, detect, install, build, SBOM/security, image/sign, publish).

Examples:

sendbuilds deploy owner/repo --docker --target kubernetes
sendbuilds deploy owner/repo --branch main --target tarball
sendbuilds deploy owner/repo --dry-run
sendbuilds deploy --local --target tarball

Flags:

  • --docker: ensure container image output is produced
  • --target: select publish targets (kubernetes, serverless, tarball, directory, container_image)
  • --dry-run: print planned steps without executing
  • --branch: deploy a specific branch
  • --local: deploy current workspace (no git clone required)
  • --build: force rebuild before deploy (skip artifact reuse/start)
  • --remote: reserved for cloud workers; currently falls back to local execution

Local deploy does not require Docker unless you request --docker or --target container_image. When no explicit Docker/target flags are set, deploy auto-detects container need (for example from sendbuild.toml targets or local Dockerfile presence) and otherwise runs local non-container flow. In local non-container mode, deploy now reuses the latest existing directory artifact and starts it automatically when possible; if start detection fails, it exits with guidance instead of rebuilding silently. When container mode is active (--docker or container target), deploy also starts the built image as a local Docker container and prints published port mappings. If you explicitly request a container target and the required local runtime is unavailable, deploy now fails instead of silently skipping container output.

Artifact Management

Inspect and manage build history:

sendbuilds artifacts list
sendbuilds artifacts list --all
sendbuilds artifacts prune --keep-last 20 --max-age 30
sendbuilds artifacts download 20260306_210619/artifact.tar.gz --out ./downloads

Debug a specific build-id:

sendbuilds debug 20260306_210619

Replay deploy from a build-id (starts container artifact if present, otherwise starts directory artifact):

sendbuilds replay 20260306_210619

Time-travel replay by date/time:

sendbuilds replay --time-machine 2026-03-06
sendbuilds replay --time-machine "2026-03-06 21:25:31"
sendbuilds replay --time-machine "2026-03-06T21:25:31+01:00"

Rollback shortcuts:

sendbuilds rollback 20260306_210619
sendbuilds rollback --to 2026-03-06

Rebase Base Images

Update only the runtime/base layer for a sendbuilds layered Dockerfile without rebuilding everything.

sendbuilds rebase

Use an explicit runtime base and target image:

sendbuilds rebase --base gcr.io/distroless/nodejs20-debian12 --image my-app:rebased

Use a local tag or Docker image ID as cache source:

sendbuilds rebase --from-image my-app:latest --image my-app:rebased
sendbuilds rebase --from-image sha256:0123456789abcdef --image my-app:rebased

If your layered Dockerfile is not in the current directory, pass --context and/or --dockerfile.

Git mode does a full rebuild (same as build --git --docker) and infers the image from the git repo name when not provided:

sendbuilds rebase --git
sendbuilds rebase --git --repo https://github.com/owner/repo --branch main

Deterministic Reproducible Builds

Use reproducible mode for stricter deterministic behavior:

sendbuilds build --reproducible

In reproducible mode, sendbuilds applies strict defaults:

  • Isolated env baseline (TZ=UTC, LANG/LC_ALL=C, PYTHONHASHSEED=0, SOURCE_DATE_EPOCH)
  • No host env passthrough (env_from_host ignored)
  • Strict sandbox mode
  • Build cache disabled
  • No install fallback retries (single deterministic install command)
  • Required lock/toolchain files enforced (for example package-lock.json/yarn.lock/pnpm-lock.yaml, Cargo.lock, go.sum, Gemfile.lock, composer.lock, .NET global.json)

Minimal config

[project]
name = "my-app"

[deploy]
artifact_dir = "./artifacts"

source, language, install_cmd, build_cmd, and output_dir are optional. If [source] is omitted, sendbuilds uses the current folder contents as build input.

Full config (all features)

[project]
name = "my-app"
language = "nodejs" # optional override

[source] # optional
repo = "https://github.com/you/my-app.git" # optional
branch = "main" # optional

[build]
install_cmd = "pnpm install --frozen-lockfile --prefer-offline" # optional override
build_cmd = "pnpm run build"                                     # optional override
parallel_build_cmds = ["pnpm run build:client", "pnpm run build:server"] # optional
output_dir = ".next"                                             # optional override

[deploy]
artifact_dir = "./artifacts"
targets = ["directory", "tarball", "serverless_zip", "container_image", "kubernetes"] # optional
container_image = "my-app:latest"                                       # optional
push_container_image = "registry.example.com/my-app:latest"             # optional: tag/push target if different from build image
verify_container_image = "registry.internal/my-app:latest"              # optional: registry reference used for manifest verification
container_platforms = ["linux/amd64", "linux/arm64"]                    # optional (buildx)
push_container = true                                                    # optional (required for multi-arch)
container_backend = "docker"                                             # optional: docker|podman|buildah|buildkit
verify_container_push = true                                             # optional: verify registry manifest after push
fail_if_container_unavailable = true                                     # optional: fail if container target requested but no backend is available
rebase_base = "gcr.io/distroless/nodejs20-debian12"                     # optional runtime rebase base

[deploy.kubernetes] # optional (used by target="kubernetes")
enabled = true
namespace = "default"
replicas = 2
container_port = 3000
service_port = 80
image_pull_policy = "IfNotPresent"

[deploy.gc] # optional automatic artifact garbage collection
enabled = true
keep_last = 5
max_age_days = 14

[output]
events = false # default hidden; set true to show EVENT {...} lines

[cache]
enabled = true
dir = "./artifacts/.sendbuild-cache"
registry_ref = "ghcr.io/your-org/my-app-buildcache" # optional buildx registry cache

[scan]
enabled = true
command = "npm audit --json --omit=dev --audit-level=high"

[security]
enabled = true
fail_on_critical = true
critical_threshold = 0
fail_on_scanner_unavailable = true
generate_sbom = true
auto_distroless = true
# distroless_base = "gcr.io/distroless/nodejs20-debian12"
# rewrite_dockerfile_in_place = false

[sandbox]
enabled = true

[signing]
enabled = true
key_env = "SENDBUILD_SIGNING_KEY"
auto_generate_key = true
key_file = ".sendbuild/signing.key"
generate_provenance = true
cosign = false
# cosign_key = "env://COSIGN_PRIVATE_KEY"

[compatibility]
target_os = "linux"
target_arch = "x86_64"
target_node_major = 20

env_from_host = ["GITHUB_TOKEN", "NPM_TOKEN"]

[env]
NODE_ENV = "production"
API_BASE_URL = "https://api.example.com"

Container publishing example:

[deploy]
targets = ["container_image"]
container_image = "registry.example.com/app:latest"
push_container_image = "registry.example.com/app:latest"
verify_container_image = "registry.example.com/app:latest"
push_container = true
container_backend = "docker"
verify_container_push = true
fail_if_container_unavailable = true

CLI examples:

sendbuilds build --image registry.example.com/app:latest --push
sendbuilds build --image registry.example.com/app:latest --backend podman
sendbuilds build --image registry.example.com/app:latest --target container_image
sendbuilds build --image localhost:5000/runtime/app:latest --push-image host.docker.internal:5000/runtime/app:latest --verify-image registry.sendara-runtime.svc.cluster.local:5000/runtime/app:latest --push --backend docker --target container_image

Successful container publish metadata is emitted as machine-readable JSON in container-publish.json and embedded in build-metrics.json, for example:

{
  "container_image": "registry/sendara/app:tag",
  "backend_used": "docker",
  "pushed": true,
  "registry_manifest_verified": true
}

Step events

When [output].events = true (or --events true), machine-readable step events are emitted to stdout:

EVENT {"type":"STEP_STARTED","channel":"build-step","step":"install","status":"running","timestamp":"..."}
EVENT {"type":"STEP_COMPLETED","channel":"build-step","step":"install","status":"completed","timestamp":"...","duration_ms":1234,"cpu_percent":5.2,"memory_mb":24,"disk_mb":300}
EVENT {"type":"STEP_FAILED","channel":"build-step","step":"build","status":"failed","timestamp":"...","duration_ms":4321,"error":"..."}

Added capabilities

  1. Build metrics: per-step duration, status, cache hit/miss accounting, plus build-metrics.json in the artifact root.
  2. Resource usage tracking: per-step CPU, memory delta, and disk delta in events and step summaries.
  3. Sandboxing controls: optional sandbox mode ([sandbox].enabled) with basic command blocking and restricted env baseline.
  4. Signed artifacts: optional HMAC-SHA256 manifest signing with artifact-manifest.json and artifact-manifest.sig.
  5. Environment variable injection: explicit [env] values and env_from_host passthrough.
  6. Multiple output targets: directory, static_site, tarball, serverless_zip / serverless_function, container_image, and kubernetes (Kubernetes manifests).
  7. Compatibility checks: optional warnings for target OS/arch/node-major mismatches, including engines.node checks when available.
  8. Multi-language support: Node.js, Python, Ruby, Go, Java, PHP, Rust, Static Sites, Shell Scripts, C/C++, Gleam, Elixir, Deno, and .NET.
  9. Multi-framework support: Next.js, Rails, Django, Flask, Spring (Maven/Gradle), Laravel, plus generic toolchain detection by language.
  10. Automatic artifact garbage collection: optional [deploy.gc] retention by count and age after each successful deploy.
  11. Security-First Buildpack (enterprise): auto-generates SBOM (sbom.json), runs vulnerability scans during build, enforces critical-CVE build failure policy, auto-switches Dockerfile final base to distroless, and emits security-report.json plus supply-chain-metadata.json.
  12. CNB lifecycle parity metadata: exports cnb/lifecycle-contract.json and cnb/lifecycle-metadata.json with standardized detect/analyze/restore/build/export phase mapping.
  13. Layered and rebase-ready container output: generated layered Dockerfiles and .sendbuild-rebase-plan.json for runtime-base upgrades.
  14. Registry-backed container cache/export: optional buildx --cache-from/--cache-to via [cache].registry_ref.
  15. First-class multi-arch container builds: optional container_platforms with buildx push flow.
  16. Provenance attestations and cosign integration: emits provenance.intoto.jsonl; optional cosign sign/attest.
  17. Deterministic reproducible mode: build --reproducible enforces locked inputs, isolated env, strict sandboxing, and deterministic install behavior.
  18. Strict container publish mode: container_image output is all-or-nothing, with backend resolution, optional push, and registry manifest verification.

Security scan failure details

When legacy security-scan fails, the error includes vulnerable package names and actionable suggestions.

Example:

EVENT {"type":"STEP_FAILED","channel":"build-step","step":"security-scan","status":"failed","timestamp":"...","duration_ms":2065,"error":"security scan failed. command=`npm audit --json --omit=dev --audit-level=high` exit=Some(1). vulnerable packages: minimist(high,fix:available), braces(high,fix:upgrade). suggestions: 1) npm audit fix 2) update vulnerable packages/lockfile 3) if blocked, pin safe versions and rebuild cache"}

Notes

  • Builds run in temporary work directories under system temp.
  • Deploy artifacts are emitted under timestamped directories in deploy.artifact_dir.
  • With target kubernetes, sendbuilds writes kubernetes/deployment.yaml and kubernetes/service.yaml into the artifact root.
  • If [deploy.gc].enabled = true, old timestamped artifact directories are pruned automatically after deploy.
  • Container publish metadata is written to container-publish.json and included in build-metrics.json when a container image is built.
  • Security-first output is written to artifact root as sbom.json, security-report.json, and supply-chain-metadata.json, and embedded in build-metrics.json.
  • CNB lifecycle parity output is written to artifact root under cnb/lifecycle-contract.json and cnb/lifecycle-metadata.json.
  • Provenance output is written as provenance.intoto.jsonl when signing provenance is enabled.
  • If signing.auto_generate_key = true, sendbuilds creates a random key in signing.key_file (default .sendbuild/signing.key) and exports it to signing.key_env when missing.
  • If both [security].enabled and [scan].enabled are true, security-first runs and legacy security-scan is skipped to avoid duplicate scanning.
  • For Next.js production runtime, prefer output: "standalone" and set output_dir accordingly.

Contributing

  1. Fork and create a branch from master.
  2. Make focused changes with clear commit messages.
  3. Run local checks before opening a PR:
cargo fmt --all -- --check
cargo check
cargo test
  1. If you changes, update README.md and sendbuild.toml examples.
  2. Open a PR with:
  • what changed
  • why it changed
  • how you tested it

CI

GitHub Actions CI runs on push and pull requests. It validates formatting, compilation, tests, and release build output for Linux and Windows.

About

One Command. Any Build

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages