tofupilot build

Last updated on November 9, 2026

The build command makes a procedure's deployment bundle on this machine, with the same steps as the cloud build. Use it when the build needs something only your network reaches, such as a private package registry. Ship the result with tofupilot deploy --prebuilt.

build
tofupilot build

The directory must contain a pyproject.toml (a uv package, possibly a member of a uv workspace). Without uv.lock, build generates one and warns: commit it to make builds reproducible.

What a bundle holds

A bundle holds the procedure's source and every package it needs as a wheel. The station installs these files without reaching any package index, so it needs no credentials for your registry. Python and uv are not in the bundle: the station installs them as for any deployment, from dl.tofupilot.app.

Stations need CLI 2.13.0 or newer to install these bundles. The bundles go to .tofupilot/output/ in the procedure folder. That folder ignores itself in git, and each build replaces the bundles of the previous one.

Platforms

When every package is pure Python, one bundle serves every platform (deployment-standalone-universal.tar.zst). Otherwise build makes one bundle per platform, for this machine by default. --platform names the stations' platforms instead, and can be repeated: linux_x86_64, linux_aarch64, macos_arm64, windows_x86_64.

Linux and Windows stations
tofupilot build --platform linux_x86_64 --platform windows_x86_64

Each bundle holds the packages its platform needs, as uv.lock describes them. A package with no published wheel for a platform is compiled here, which works for another platform than this machine's only when the package is pure Python. Otherwise the build fails and names the package: build on a machine of that platform, or pin a version that publishes a wheel for it.

Private registries

Each package is downloaded from the index uv.lock records for it. build knows the indexes declared in pyproject.toml, in the project's or your own uv.toml, and in uv's environment variables (UV_INDEX, UV_DEFAULT_INDEX, UV_INDEX_URL, UV_EXTRA_INDEX_URL). A registry that needs credentials gets the ones uv reads:

SourceExample
Environment variables, <NAME> being the index name uppercased, other characters replaced by _UV_INDEX_COMPANY_REGISTRY_USERNAME, UV_INDEX_COMPANY_REGISTRY_PASSWORD
Credentials written in the index URLhttps://ci:token@pypi.example.com/simple/
~/.netrcan entry for the registry's host
an index named company-registry
export UV_INDEX_COMPANY_REGISTRY_USERNAME=ci
export UV_INDEX_COMPANY_REGISTRY_PASSWORD="$REGISTRY_TOKEN"
tofupilot build

Credentials stored by uv auth login or a keyring provider are not passed on. Use one of the sources above instead.

Git state

In a git repository, each bundle records the commit it was built from and whether the project had uncommitted changes. build lists those changes when there are some, and the deployment shows the commit with a modified badge. The tofupilot.json that tofupilot link writes counts as a change until you commit it or add it to .gitignore.

Limits

  • A uv flat index (a folder or a page of wheel links) is not supported.
  • A bundle larger than 95 MB cannot be uploaded.
  • A git or path dependency gets its build backend from PyPI, not from your registry.
  • A package compiled from source on a musl Linux machine (an Alpine container) is refused: stations run glibc. Build on a glibc Linux machine such as Debian or Ubuntu.

--json

With --json, build prints one object typed "build": the runtime_version, the git state, and the artifacts, each with its path, platform (null for a bundle that serves every platform) and size_bytes.

How is this guide?

On this page