github wavelens/gradient v2.0.0

3 hours ago

Gradient v2.0.0

First stable release. Nix flakes evaluated, derivations built on remote workers, outputs in a built-in binary cache.

New Features

Teams

  • Teams with grants on projects and caches, invitations, join requests and a team Admin role.
  • Team workers: registered workers with access to every granted project.
  • OIDC and SCIM groups mapped onto team membership instead of project roles.
  • Teams, grants, workers and members declarable in services.gradient.state.
  • Team creation behind --permissions-create-team.
  • Team pages in the web UI: overview, members, workers, settings and recent evaluations of granted projects.
  • Mail actions addressable as team:<name>.

Gradient.CI Servers

  • A connection token linking an instance to a team.
  • A server connection to a worker, with the caller's tokens checked against acceptedServerTokensFile.
  • An admin page for base workers, with Connect base server.
  • The state and last error of each connection in the web UI.

SSH builds

  • An SSH server for ssh-ng clients and nixos-rebuild build hosts.
  • A build request as an evaluation on the worker pool, with an evaluation per connection.
  • nix copy into the project caches. nix.gradient-ssh as a remote builder.
  • Build logs streamed to the Nix client as build activities.

Evaluations

  • Import from derivation: a derivation built on the fleet, its outputs awaited by the evaluation (#668).
  • Live progress: thunks, flake input downloads, the nar_fetch and nar_import phases, upload progress (#658).
  • An entry point per attribute, with imported derivations tagged.
  • Abort and retry of a single build from the log page (#673). A whole evaluation is retryable too.
  • retry_failed_builds per task: permanent failures stay failed until a retry.
  • Wildcard grammar: * for any attribute, ** for a nested set below it, x86_64-* for part of a name, ! to exclude.
  • Evaluation summary and entry point search.
  • Parallel evaluations from gradient eval and gradient build, with fork workers.

Scheduling

  • A time estimate per build over download, build and upload, learned per path and per megabyte.
  • Build resource usage from the Nix daemon build result, in place of the cgroup sampler (#357).
  • Large transfers held back while the upload or download slots are full.
  • A RAM reservation per build. A retry for an out-of-memory build. An early failure for an oversized build.
  • A QoS bonus from the scheduler for prioritized builds and evaluations.
  • Cluster jobs: a multi-worker cluster per evaluation, on idle workers of a zone, with reservations and member signals.

Caching and storage

  • Pull-through as a cache option.
  • Refusal codes from upstream caches. An unresponsive upstream: another probe instead of a build.
  • Deep GC over storage, shard by shard, paced and resumable.
  • S3 build log sharding, the same as for local logs.
  • Download concurrency from storage: 16 connections. Upload concurrency: 8.
  • A configurable NAR transfer chunk size on server and worker.

Web UI

  • A storage and transport health board.
  • A job board with scheduler and health rows, job decisions and live worker load.
  • A full-width log page, with the builds list in a drawer on phones (#766).
  • Phone layouts: swipeable stat rows, icon-only buttons, row menus, two-line entry point rows.
  • Skeletons for the dashboard, cache stats, NAR tables and the task page.
  • An SSH keys settings page.
  • frontend.logoUrl for a custom logo on the sign-in pages.
  • Editable Matrix and Slack actions (#689).
  • Missing worker connections marked on the task page (#716).

Nix and deployment

  • The standalone host as a VM with nix run .#standalone and as an OCI image on ghcr.
  • environmentVariables options for the server and the worker.
  • A public URL option for a deployment behind a port mapping.
  • The deploy module renamed to gradient-client and nix.gradient-ssh as a remote builder.
  • Gradient as the preferred remote builder, with speedFactor 128.
  • gradient-evalbench: a VM benchmark with an HTML report and a published bundle.
  • A latest branch for stable releases and a beta branch for every release, moved by the release workflow.
  • A signed build provenance and an SBOM for the standalone image.

API and protocol

  • A protocol version agreement before the first message, with per-field protocol versions.
  • Authenticate with the caller's tokens, out of traces.
  • Cluster membership, roster and signals, with handover and path list messages for shared workers.
  • New endpoints for teams, ssh keys, upstream caches and admin draining.
  • POST /builds/{build}/abort, /builds/{build}/retry, /evals/{evaluation}/retry and /evals/{evaluation}/summary.
  • /caches/{cache}/upstream-caches in place of /caches/{cache}/upstreams and /hooks/{git_host}/... in place of /hooks/{forge}/....

Bug Fixes

  • A retry for the builds of a failed or aborted evaluation. An abort for queued builds.
  • Substituted outputs out of the build history. Unmeasured values as null.
  • A crashing evaluation attribute: only itself failed. Every failed attribute under its own source (#788).
  • The evaluation memory cap during a call. A crashed batch member, listed member by member.
  • Exit code 2 as an out-of-memory kill.
  • A worker after a lost network: reconnect (#782).
  • An outdated upstream file size on a NAR body: accept it when the hash matches.
  • An upstream cache with reset HTTP/2 streams: pin it to HTTP/1.1 and resume its broken NAR body (#698).
  • First stored content for a store path. An upload order until the row commit.
  • A failed build's reason as an error line in its log. Missing log chunks as placeholder lines.
  • Streamed build log lines, with the package named once.
  • Job offers chunked by encoded size. No worker connection lost to a large offer.
  • A job failure behind its log chunks, keeping the end of a failed build log.
  • Worker ids owned by base workers or other connections: refused. Frames read before authentication: capped.
  • An integration dropped from the state file: deleted or unmanaged. Teams applied before projects.
  • A custom role in use by a team grant: no deletion.
  • A hand-managed team Admin: out of OIDC and SCIM group removals.
  • A deleted team's workers: jobs stopped on the granted projects.
  • The frontend session over a 429 from /user. Rate-limited requests retried. Search state over an evaluation switch.
  • Percent charts capped at 100% (#678).
  • The dependency graph from build inputs only, laid out in linear time.
  • Umlauts as ae/oe/ue in name slugs.
  • ssh:// repository URLs with owner and repository parsed. An approval in Gradient without a PR review submission.
  • The Slack webhook URL: out of delivery errors (#751).
  • An SSH build without a connected worker: abort. Nix clients learn the reason (#717).
  • The full error chain for Nix clients. Build logs as build activities (#718).
  • A request's error: out of the shared evaluation.
  • The standalone container with a console, bound to localhost and with a persisted VM store. A PATH for docker exec (#729).
  • An eval cache shared between the evaluators of a flake. A failed attribute evaluated again, not read from a cached failure. A new copy of a fetched source after garbage collection of an earlier copy.
  • Evalbench Postgres plan output in a file instead of the serial console.
  • update-version with pre-release versions and every frontend workspace package.

Performance

  • Queued NARs committed in a single transaction, narinfo rows signed inside the batched commit, each ingest step on the actor's transaction.
  • Graph rows locked FOR NO KEY UPDATE, so foreign-key checks wait behind no flush.
  • Dependency counting from a single read of the evaluation's jobs. Counters in a single SQL call per level.
  • A new evaluation estimated from the evaluations outside the most common values. Status counting for the evaluation list from the index alone.
  • Startable build offers without waiting on the graph writer. Eval dispatch woken on evaluation creation.
  • The derivation closure walked concurrently in waves of 256, each batch's .drv files and sources pushed during the evaluation.
  • A window of 128 in flight for small uploads. An upload slot freed after its transfer.
  • Cache signing keys and stored secrets decrypted once, not per signature.
  • Derivation paths resolved in the eval worker's list call, without the resolve phase.
  • @gradient/ui free of side effects. Unused UI parts leave the initial bundle.
  • No nix flake archive when every locked input is in the store. A cloned tree added as its source path directly.
  • The upstream probe woken on commit, asking about the dependencies of wanted jobs in the same round.

Don't miss a new gradient release

NewReleases is sending notifications on new releases.