Changelog
What's new in Once
Every user-facing change to Once, newest first. Subscribe to keep up.
-
Explainable input fingerprints
Permalink →Evidence records now explain why a build's inputs changed, not only that they changed. Alongside the input digest it already tracked, Once records a versioned input fingerprint that breaks the digest down into labeled components for sources, generated inputs, dependencies, module code, toolchains, command shape, and environment configuration.
Each component carries a category, a stable label, and its own digest, so two runs can be compared to see exactly which part of the input moved. Targets that run several actions aggregate their per-action fingerprints into a single target-level view.
The fingerprint is available from both command and agent evidence queries, and older evidence stays readable because the field is optional. Raw command arguments, toolchain identities, and environment values are represented only by their digests and are never stored in plain text, so the fingerprint stays safe to share.
-
Faster native project discovery
Permalink →Once now discovers native Cargo, Mix, and future ecosystem projects with one shared filesystem pass. Workspace include and exclude patterns prune unrelated directories before Once enters them, reducing startup work in large repositories without changing the targets that discovery produces.
Discovery also keeps its own memory usage predictable. Project kinds that own nested packages retain only their shallowest matching roots, while kinds that recognize every nested project have a 16 mebibyte retained-result limit. Once stops with guidance for narrowing the workspace if that limit is reached, instead of allowing the number of matching directories to cause unbounded memory growth.
-
Near-instant unchanged builds
Permalink →Once now returns almost immediately when nothing relevant has changed. A build that already matches the cache no longer revalidates the whole graph on every invocation. Instead, Once records what changed since the last successful build and reuses the previous result when the sources, declared outputs, environment, and tools it observed are all unchanged.
Input checking is also cheaper. Once validates unchanged files by their metadata rather than rereading their contents, so a repeat build no longer pays to rehash the entire dependency tree. When a cached result is reused, only the outputs that actually differ are restored. Together these reduce both the time and the memory an unchanged or lightly changed build needs.
Correctness is preserved conservatively: any change to a watched source or output, a relevant environment variable, or an observed tool on disk falls back to a full validation before the fast path is trusted again.
-
Native Cargo project graphs
Permalink →Once can now read an existing
Cargo.tomland turn it into a typed, cacheable build graph. Rust developers can build, run, and test a workspace without first translating it intoonce.toml.Native discovery understands Cargo workspaces and the locked dependency closure from
Cargo.lock, including registry, Git, and path packages. Each workspace member and locked dependency compiles as its own action, so unchanged work can be restored independently from a local or remote cache. Procedural macros and build scripts are modeled as their own targets so they rebuild only when their own inputs change.Once keeps
Cargo.tomlandCargo.lockauthoritative and uses the Rust toolchain selected by the project's configuration. Test targets report their results through the same normalized shape as the other ecosystems, so scheduled runs, change-scoped selection, and summaries work the same way.Start by running
once query native-project cargo, inspect the derived targets withonce query targets, then useonce build,once run, andonce testwith the target identifiers Once reports. -
Bounded memory scheduling for local actions
Permalink →Once now schedules concurrent local actions against a memory budget. The default is two thirds of the memory visible to the host or container, while the new global
--memory-limitoption lets constrained machines choose a smaller budget.Builds, lint targets, run targets, literal commands, scripts, and test workers share the same limit. Actions without a declared estimate receive a conservative default, and oversized actions run alone instead of waiting forever.
Large command streams, file outputs, directory outputs, and cache uploads or downloads now move through bounded buffers and temporary files instead of requiring complete artifacts in memory.
-
Native Mix project graphs
Permalink →Once can now read an existing
mix.exsand turn it into a typed, cacheable build graph. Elixir developers can build an application, run formatting and dependency checks, execute tests and Mix tasks, and assemble releases without first translating the project intoonce.toml.Native discovery understands locked Hex, Git, path, Mix, and Rebar 3 dependencies. Each package compiles as its own action, so unchanged dependency work can be restored independently from a local or remote cache. The graph also keeps development, test, and production environments separate.
Once uses the Elixir and Erlang versions selected by the project's toolchain configuration while keeping
mix.exsandmix.lockauthoritative. Umbrella applications and nested Mix projects receive package-qualified targets, and structured diagnostics explain unsupported dependency build managers or missing materialized sources.Start by running
once query native-project mix, inspect the derived targets withonce query targets, then useonce build,once run, andonce testwith the target identifiers Once reports. -
Device-specific Apple app size analysis
Permalink →Once can now produce ad-hoc signed app archives for one Apple device model at a time with
apple_thinned_package. Keeping each model in its own target makes the variants independently cacheable and ready for size-analysis services such as Sentry without the noise of a universal build.The target validates device builds, uses Xcode's thinning tool, re-signs embedded bundles, and writes a deterministic archive plus a stable manifest. Existing
apple_applicationbundles now include the supported-platform metadata that Xcode requires for thinning. -
"New blog post: Automation needs a git"
Permalink →The first post on the Once blog is live. "Automation needs a git" is Pedro's account of why Once exists: the search for a shared substrate for automation, the incremental shell-based API for decorating existing scripts, and native support for ecosystems starting with Rust. Read it under the blog.
-
A blog for ideas from the Once team
Permalink →The Once website now has a blog for longer-form notes about build graphs, reusable automation, and the ideas shaping the project.
Posts include their authors and Gravatar portraits. The list is paginated, each post has its own generated Open Graph image with author portraits, and readers can subscribe through Really Simple Syndication or Atom feeds. Markdown is compiled with MDEx, with highlighted code windows built from Noora components.
-
Cacheable linting with normalized findings
Permalink →Once can now run lint targets through the same graph, cache, evidence, and remote-execution model used by builds and tests. The first integrations cover Ruff, golangci-lint, ESLint, RuboCop, Credo, detekt, and SwiftLint.
once lintkeeps each analyzer's native configuration authoritative while presenting one finding model and failure policy to humans, automation, and coding agents. Project modules can add another analyzer through the documented lint provider and portable report contract.The bundled ESLint starter includes its required flat configuration, Credo limits analysis to declared sources, and RuboCop prepares Ruby for portable report conversion. Invalid custom lint providers now return structured repair diagnostics before their actions run.
-
Documentation now lives in the Once app
Permalink →The documentation moved from a separate static site into the Once web application, served under
/docs. It is rendered natively with the Noora design system, so the docs and the marketing site now share one look and feel.This unlocks upcoming interactive features like a package registry and live content, and lets the docs run on the same infrastructure as the rest of Once.
-
Refreshed marketing site and a changelog
Permalink →The Once home page was rebuilt around the idea of build once, reuse everywhere, with a new hero, tabbed build examples for iOS, Android, Rust, and Zig, and the list of natively supported languages and ecosystems.
This changelog is new too. Every user-facing change to Once will show up here, and you can subscribe over RSS or Atom.