heph Build System
website·Indexed 30 days ago
https://hephbuild.github.io/hephA build system featuring target-based caching, approval gates for irreversible actions, and a credential system for managing identities. It supports codegen modes (copy and in_place), remote shared caching, and deferred values for dynamic target options.
What's inside heph
- heph is an open-source build system and task orchestrator. It operates by defining targets, hashing their inputs, and executing actions in parallel within a sandbox. The system uses content-addressing for outputs to ensure that identical inputs produce byte-identical artifacts across different environments, such as local laptops and CI pipelines.
Understand heph execution and caching enforcement
heph ensures build correctness and caching guarantees through a three-step enforcement process:
- Input Hashing: Before execution, all sources, tool versions, environment variables, and rule definitions are hashed into a single digest.
- Hermetic Execution: Actions run within a sandbox that exposes only the explicitly declared inputs, preventing undeclared dependencies from affecting the build.
- Content-Addressed Outputs: The input digest serves as the key, and the resulting output bytes serve as the value, enabling reliable caching.
Caveat: Targets that are non-hermetic opt out of these caching guarantees and should be used sparingly.
Understand the heph build model and caching
heph treats a build as a directed graph of targets. Each target defines its inputs and the action required to produce its outputs. To optimize performance, heph hashes all declared inputs (including sources, dependencies, and the toolchain). If the resulting digest matches a previous run, heph records a cache hit and returns the cached output instead of re-executing the build action. Any input not explicitly declared is invisible to the build sandbox.Understand the Driver component in Targets & Rules
A driver is the system component responsible for knowing how to execute a target's action. The plugin provides a specific driver implementation calleddevenv_runner.Use the Buildfile plugin to define targets via Starlark
The buildfile plugin is a package provider that scans the workspace for BUILD files containing Starlark code. It evaluates these files to extract target definitions, including their drivers, configuration, labels, and transitive dependencies, which are then processed by the build engine. The plugin supports customizable BUILD file naming via glob patterns and allows the use ofload()statements to share symbols and reuse common definitions across multiple BUILD files in the workspace.Understand the role of Drivers in the Go build plugin
In this build system, a driver serves as the execution backend responsible for running specific types of targets. The plugin registers nine internal drivers:go_toolchain,go_golist,go_compile,go_testmain,go_lint,go_lint_gate,go_lint_fix,go_format, andgo_format_check. These drivers are internal implementation details and should not be interacted with directly by the user.Run shell commands in sandboxed builds using pluginexec
Thepluginexecplugin manages the execution of shell commands within sandboxed target builds. It handles dependency injection, environment variable setup, andPATHresolution for required tools. It supports two execution drivers:execandbash. Additionally, it enables interactive shell debugging through PTY allocation.Define Go build variants using provider_state
Go targets in heph require a build variant to compile. A build variant is a named set of factors including target OS, architecture, build tags, and compiler/linker flags. Variants are declared using
provider_stateand are scoped to the Go module (the directory containinggo.mod).Inheritance is supported via the
inheritfield. When inheriting, list fields (tags,goexperiment,gcflags,ldflags) are replaced by the child variant, not merged.provider_state(provider = "go", variants = { "base": {"goos": "linux", "goarch": "amd64"}, "release": { "inherit": "base", "goexperiment": ["arenas"], "gcflags": ["-l"], "ldflags": ["-s", "-w"], "tags": ["prod"], }, })Use the heph Go provider for build target generation
Thegoprovider in heph provides Go language support by analyzing Go packages to automatically generate targets for building libraries, binaries, and tests. It handles package metadata reading, source file resolution, and module dependency management. The provider relies on several managed drivers to execute the underlying toolchain operations:go_toolchainfor provisioning,go_golistfor metadata analysis,go_compilefor compilation,go_testmainfor test main generation, and a suite of lint/format drivers includinggo_lint,go_lint_gate,go_lint_fix,go_format, andgo_format_check.Understand the role of a Driver in target execution
A driver is the system component responsible for executing a target's action. It transforms a resolved target into runnable work. For example, thehttp_fetchdriver is used to handle targets that require fetching data over HTTP.Configure tool cache access modes in heph
The
accesssetting in heph is an assertion about a tool's concurrency safety regarding its cache. Choosing the wrong mode can lead to cache corruption or unnecessary serialization of tasks.exclusive(Default): Ensures only one consumer runs at a time by holding a lock for the entire duration of the run. Use this for most tools that do not explicitly document concurrent writer safety.shared: Allows concurrent access. Use this only for tools that are safe under concurrent writers (e.g., Go's build and module caches, which are content-addressed).
Understand the role of a Provider in target discovery
A Provider is responsible for discovering targets and making them available to the build engine. It does not execute the build work itself; instead, the actual execution is delegated to the specific driver named by each target.