Build automation CLI with step events, caching, auto-detection, metrics, sandbox controls, artifact signing, and multi-target outputs.
- 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.
sendbuilds build --config sendbuild.tomlUnused dependency detection (best-effort, per language):
sendbuilds build --unused-depssendbuilds 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 --allConfig 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"curl -fsSL https://sendara.cloud/sendbuilds/install.sh | bashRelease assets are packaged for direct CLI install:
- Linux/macOS:
.tar.gz(containssendbuilds+install.sh) - Windows:
.zip(containssendbuilds.exe+install.ps1)
Linux/macOS:
tar -xzf sendbuilds-linux-x86_64.tar.gz
./install.sh
sendbuilds --helpWindows PowerShell:
Expand-Archive .\sendbuilds-windows-x86_64.zip -DestinationPath .\sendbuilds
.\sendbuilds\install.ps1
sendbuilds.exe --helpWindows note:
sendbuilds.exeis a CLI, so double-clicking it in Explorer opens/closes quickly by design.- Run it from Terminal/PowerShell (
sendbuilds.exe --help).
Build and run the CLI locally:
cargo build --release
./target/release/sendbuilds --help
./target/release/sendbuilds build --config sendbuild.tomlOn Windows PowerShell:
cargo build --release
.\target\release\sendbuilds.exe --help
.\target\release\sendbuilds.exe build --config sendbuild.tomlRun without a release build:
cargo run -- build --config sendbuild.tomlLocalhost testing flow for a web app:
- Build with
sendbuilds(buildcommand). - Enter the produced artifact folder under
deploy.artifact_dir. - 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.
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 --git <repo> --docker [--branch <name>] [--image <tag>]
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.
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>/artifactsand 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 examplenotsliver/sendara-landing)https://github.com/owner/repohttps://github.com/owner/repo.git
sendbuilds deploy owner/repoThis 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 tarballFlags:
--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.
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 ./downloadsDebug a specific build-id:
sendbuilds debug 20260306_210619Replay deploy from a build-id (starts container artifact if present, otherwise starts directory artifact):
sendbuilds replay 20260306_210619Time-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-06Update only the runtime/base layer for a sendbuilds layered Dockerfile without rebuilding everything.
sendbuilds rebaseUse an explicit runtime base and target image:
sendbuilds rebase --base gcr.io/distroless/nodejs20-debian12 --image my-app:rebasedUse 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:rebasedIf 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 mainUse reproducible mode for stricter deterministic behavior:
sendbuilds build --reproducibleIn 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_hostignored) - 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)
[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.
[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
container_platforms = ["linux/amd64", "linux/arm64"] # optional (buildx)
push_container = true # optional (required for multi-arch)
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"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":"..."}
- Build metrics: per-step duration, status, cache hit/miss accounting, plus
build-metrics.jsonin the artifact root. - Resource usage tracking: per-step CPU, memory delta, and disk delta in events and step summaries.
- Sandboxing controls: optional sandbox mode (
[sandbox].enabled) with basic command blocking and restricted env baseline. - Signed artifacts: optional HMAC-SHA256 manifest signing with
artifact-manifest.jsonandartifact-manifest.sig. - Environment variable injection: explicit
[env]values andenv_from_hostpassthrough. - Multiple output targets:
directory,static_site,tarball,serverless_zip/serverless_function,container_image, andkubernetes(Kubernetes manifests). - Compatibility checks: optional warnings for target OS/arch/node-major mismatches, including
engines.nodechecks when available. - Multi-language support: Node.js, Python, Ruby, Go, Java, PHP, Rust, Static Sites, Shell Scripts, C/C++, Gleam, Elixir, Deno, and .NET.
- Multi-framework support: Next.js, Rails, Django, Flask, Spring (Maven/Gradle), Laravel, plus generic toolchain detection by language.
- Automatic artifact garbage collection: optional
[deploy.gc]retention by count and age after each successful deploy. - 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 emitssecurity-report.jsonplussupply-chain-metadata.json. - CNB lifecycle parity metadata: exports
cnb/lifecycle-contract.jsonandcnb/lifecycle-metadata.jsonwith standardized detect/analyze/restore/build/export phase mapping. - Layered and rebase-ready container output: generated layered Dockerfiles and
.sendbuild-rebase-plan.jsonfor runtime-base upgrades. - Registry-backed container cache/export: optional buildx
--cache-from/--cache-tovia[cache].registry_ref. - First-class multi-arch container builds: optional
container_platformswith buildx push flow. - Provenance attestations and cosign integration: emits
provenance.intoto.jsonl; optional cosign sign/attest. - Deterministic reproducible mode:
build --reproducibleenforces locked inputs, isolated env, strict sandboxing, and deterministic install behavior.
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"}
- Builds run in temporary work directories under system temp.
- Deploy artifacts are emitted under timestamped directories in
deploy.artifact_dir. - With target
kubernetes,sendbuildswriteskubernetes/deployment.yamlandkubernetes/service.yamlinto the artifact root. - If
[deploy.gc].enabled = true, old timestamped artifact directories are pruned automatically after deploy. - Security-first output is written to artifact root as
sbom.json,security-report.json, andsupply-chain-metadata.json, and embedded inbuild-metrics.json. - CNB lifecycle parity output is written to artifact root under
cnb/lifecycle-contract.jsonandcnb/lifecycle-metadata.json. - Provenance output is written as
provenance.intoto.jsonlwhen signing provenance is enabled. - If
signing.auto_generate_key = true,sendbuildscreates a random key insigning.key_file(default.sendbuild/signing.key) and exports it tosigning.key_envwhen missing. - If both
[security].enabledand[scan].enabledare true,security-firstruns and legacysecurity-scanis skipped to avoid duplicate scanning. - For Next.js production runtime, prefer
output: "standalone"and setoutput_diraccordingly.
- Fork and create a branch from
master. - Make focused changes with clear commit messages.
- Run local checks before opening a PR:
cargo fmt --all -- --check
cargo check
cargo test- If you changes, update
README.mdandsendbuild.tomlexamples. - Open a PR with:
- what changed
- why it changed
- how you tested it
GitHub Actions CI runs on push and pull requests. It validates formatting, compilation, tests, and release build output for Linux and Windows.