The problem
Pushing every artifact on every green build is slow and introduces risk: you may push a binary whose inputs did not change, overwriting a known-good artifact with an identical but unverified one. It also wastes CI time and registry storage on uploads that change nothing. You want to push only the artifacts whose build outputs actually changed since the last release.How it works
Selective Delivery determines what changed using the content hash of each build output, not the git SHA or a timestamp. If Bazel produces the same output digest for a target, that target is not pushed, even if unrelated files changed in the same commit. This is the same cache-key logic Bazel uses internally, applied at delivery time. From trigger to upload, a delivery run:- Triggers on green builds of release branches. Running on
mainis typical, but you have full control over which branches and tags delivery runs on in your CI configuration, and you declare the build and test jobs it depends on there too, so delivery only runs when they pass. - Compares output digests against the prior release to find the targets whose outputs actually changed. With Build without the Bytes, the comparison works from hashes alone and never downloads an artifact, so determining what to deliver costs almost nothing, even across hundreds of deliverable targets.
- Builds resolved targets with version-control stamping enabled, so the pushed artifact carries the correct build metadata.
- Runs push logic in parallel across the delivery targets, uploading each changed artifact to its configured destination: a container registry, object store, or other target.
- Produces a delivery manifest: a structured record of every target’s outcome and CI metadata, uploaded as a CI artifact. The manifest is customizable and can be enriched with AXL hooks, for example to attach OCI image digests or feed downstream deployment tooling.
Why digests, not git SHAs
Version stamping is the usual obstacle here: if every artifact embeds the commit SHA, then every artifact differs on every commit and nothing can be skipped. Selective Delivery sidesteps the trap by comparing unstamped outputs to detect change, then rebuilding only the changed targets with stamping for the actual push. You get accurate change detection and correctly-stamped artifacts.What you get
- Faster delivery. Only changed targets rebuild and upload, so release pipelines finish in a fraction of the time.
- Lower cost. No redundant uploads burning CI minutes, registry storage, and network egress.
- Safer releases. Known-good artifacts are never overwritten by unverified rebuilds of identical content.
- Simple configuration. Adding a new delivery target is as easy as adding a new Bazel target; teams configure and maintain their own.
- Auditable. Each delivered artifact traces back to the monorepo state that produced it.
Selective Delivery is implemented as the
aspect delivery AXL task. The task page covers configuration, the delivery script contract, and how to wire it into your CI pipeline.
