Build Artifact
A build artifact is an output retained from a build. This article focuses on release artifacts such as container images, JARs, wheels, and signed packages: the outputs selected for validation, deployment, and possible recovery.
DORA recommends deploying CI packages from an artifact repository, with environment configuration supplied separately. Keeping a candidate available lets later stages retrieve the same package instead of assuming that another build from its source is equivalent.
Configuration separation makes unchanged promotion easier, and the table above describes that default design. An environment-specific or platform-specific package is still an artifact, but it is a distinct candidate that needs appropriate checks. Whether a file is a useful promotion unit depends on what the release must install and run.
What it contains
In the Reproducible Builds definition, the specified artifacts are the primary outputs whose bytes must be reproducible, typically excluding logs. CI systems may also retain logs and test reports as artifacts. State which meaning you use; here the focus is the software package being released.
| Belongs in the artifact | Stays outside when one candidate is promoted unchanged |
|---|---|
| Compiled code and static assets | Hostnames, endpoints, connection strings |
| Bundled dependencies or a manifest for separately installed dependencies | Credentials and keys |
| The runtime it expects, where the format includes one | Feature flag states, per-environment limits |
| Its own identity and a link to the source it came from | Settings that differ between staging and production |
Package formats have different boundaries. A wheel contains one Python distribution, not the complete runtime environment. A deployment can install that wheel with an approved set of pinned, hash-verified dependency wheels and a specified interpreter. Validate the installed combination. Uncontrolled dependency selection can change that combination even when the application wheel stays identical.
Identity: connect a version to immutable content
A release label such as 2.4.1 needs an unambiguous mapping to retained content. If it can be overwritten, the label alone cannot establish which bytes ran. An immutable repository mapping can supply that identity; recording and checking the digest makes the content comparison explicit.
So carry two identifiers with different jobs.
- A human-facing version, often following semantic versioning, communicates compatibility intent for the declared public API. It does not by itself establish operational safety.
- A content digest identifies the bytes used by deployments, incident records, and rollback candidates. Identical output from a second build has the same digest; record the separate build invocation and its provenance without inventing a different content identity.
Provenance describes the builder, process, and recorded inputs so a consumer can check how an artifact was produced. Its completeness and trust depend on the collection and verification system. SLSA Build L1 records may be incomplete or unsigned, so they aid investigation without providing tamper protection.
Where it lives
An artifact repository is not just storage; it is the thing that makes “the same artifact” a meaningful phrase across environments and across time. Three properties matter more than which product you use.
- Immutability. Keep the release identity tied to the same bytes. A mutable tag makes records ambiguous when they contain only that tag; a retained digest still identifies the selected content.
- Retention. Keep the previous artifact, its identity, and the configuration and dependencies needed to run it. Recovery also requires compatibility with the current schema, data, and interfaces. Restoring executable code does not reverse actions or data changes that already occurred.
- Deployment records. Record the artifact and configuration actually deployed in each environment, so an investigation can start from an identified release.
Four ways it goes wrong
- Substituting an unverified rebuild. The same source revision can produce different output. Reuse the tested candidate or establish output identity and check the new invocationโs provenance and approval requirements. Different output needs validation as a new candidate.
- Selecting floating dependencies during deployment. Fetching unpinned packages can make two installations differ. Installing a validated set of pinned, hash-verified files is compatible with preserving release identity when runtime and installation conditions are also controlled.
- Relying on mutable tags. Kubernetes chooses an image according to container startup, pull policy, and local cache.
Alwaysresolves the tag when launching a container;IfNotPresentcan reuse a cached image, andNeverrequires one locally. Node startup time does not identify the running version. Record the actual image digest and compare it with the approved candidate. - Baking in changing environment settings. Changing such a value requires rebuilding that package. Prefer runtime configuration where suitable; if a build variant is necessary, give it explicit identity and verification.
Trace the running release to the retained package and the checks that examined it. environment promotion preserves that connection across environments; a reproducible build can establish matching output from separate builds. You Tested a Different Binary explains how these practices fit into a delivery pipeline.
References
- DORA, Deployment automation
- Reproducible Builds, Definitions
- SLSA v1.2, Build Track Basics
- PyPA โ Binary distribution format
- pip โ Secure installs
- Kubernetes โ Images
Discover more from Insightful Data Lab
Subscribe to get the latest posts sent to your email.
