Skip to main content

Configuration

.hephconfig sits at the root of your workspace and marks it as a heph project. It registers the plugins your build uses and tunes a handful of engine-level settings. It is YAML.

.hephconfig
version: 1.2.3
plugins:
- builtin: buildfile
- builtin: bash

Pinning the version

.hephconfig
version: v1.2.3

version pins the heph release for this workspace so every machine and CI job runs the same binary. When the running binary differs from the pin, heph automatically downloads the pinned release and re-execs into it on startup — the rest of the run is served by the pinned version. The downloaded binary is cached in ~/.heph/versions/<tag>/ and reused on subsequent runs.

To disable automatic self-upgrade for a process tree, set HEPH_NO_SELF_UPDATE to any non-empty value:

export HEPH_NO_SELF_UPDATE=1
heph run //...

This is useful in sandboxed environments or where you manage toolchains yourself.

Keys

Every key below is optional.

KeyTypeDefaultDescription
versionstringunsetPins the heph release for this workspace. When set, heph automatically downloads and re-execs into the pinned version on startup. See Pinning the version.
pluginslist of plugin entries[]Plugins to register. Each entry sets exactly one of builtin, path, or url, plus an optional options map and, for url: entries, an optional checksum.
homeDirpathunsetWhere heph keeps its home and cache.
fs{skip: string[]}{}Workspace-wide ignore patterns shared with all tree-walking plugins.
memCache{perEntryBytes, capacityBytes}unsetIn-memory cache sizing.
cache{spillThresholdBytes: number}{}Durable local-cache tuning.
cachesmap of {uri, read, write, concurrency}{}Named remote (shared) caches.
fuse{enabled: true | false | "auto"}offSandbox overlay mode.
lock{backend: fs | mem}fsExecute-phase lock backend.
telemetry{enabled: true | false}{} (enabled)Anonymous usage reporting. Set enabled: false to opt out.

Registering plugins

plugins is a list of entries. Each entry must set exactly one of:

KeyLoads
builtinA compiled-in plugin by name (e.g. buildfile, exec).
pathA local *-plugin.json manifest (relative to the workspace root, or absolute).
urlA remote *-plugin.json manifest — downloaded and cached in ~/.heph/plugins/.

Each entry also accepts an optional options map passed to that plugin:

.hephconfig
plugins:
- builtin: buildfile
options:
patterns: [BUILD, "*.BUILD"]
- builtin: exec
options:
path:
- /usr/local/bin
- /usr/bin
- /bin
- path: ./path/to/my-plugin.json
options:
some_option: value

url: entries also accept a checksum field to pin the downloaded manifest — see Pinning manifests with checksums.

The keys allowed inside options are defined by each plugin — see its page (for example Buildfile, Exec, Go). The engine only wires plugins together; it does not interpret their options.

note

Some plugins are built-in and always available (group, fs, hostbin, query); others must be listed here before a target can use them. Each plugin page states which.

External plugins (path: and url:)

An external plugin ships as a shared library (cdylib) paired with a *-plugin.json manifest. The manifest names the plugin and lists per-platform library artifacts; heph picks the right one for the current host.

path: points at a manifest on disk (relative to the workspace root, or absolute, or ~/-prefixed). url: fetches the manifest from a URL; the downloaded manifest and library are cached in ~/.heph/plugins/<os>-<arch>/ and reused on subsequent runs.

.hephconfig
plugins:
# Local manifest on disk
- path: ./path/to/my-plugin.json

# Remote manifest — downloaded and cached automatically
- url: https://github.com/hephbuild/heph-artifacts-v1/releases/download/latest/heph-go-plugin.json

path: and url: plugins are supported on Unix only.

Pinning manifests with checksums

A url: entry accepts an optional checksum field that pins the SHA-256 of the downloaded manifest. heph verifies the manifest against this digest before trusting anything it declares — a mismatch is a hard error.

.hephconfig
plugins:
- url: https://github.com/hephbuild/heph-artifacts-v1/releases/download/latest/heph-go-plugin.json
checksum: sha256:<hex>

The checksum is published alongside each manifest as a <manifest>.sha256 sidecar file (e.g. heph-go-plugin.json.sha256). Copy the value from that sidecar into checksum: to lock the manifest to a known-good digest.

The field anchors a trust chain: the config pins the manifest → the manifest pins each per-host artifact (cdylib) with its own checksum entry → the loaded binary is verified. Both levels must pass before any plugin code runs.

FormatMeaning
sha256:<hex>SHA-256 digest in lowercase hex. The only supported algorithm.

checksum is optional. Omitting it skips manifest verification; per-artifact checksums embedded in the manifest still apply when present. checksum is only valid for url: entries — builtin: and path: entries reject it.

fs — workspace ignore patterns

fs.skip is a list of workspace-root-relative patterns shared with every tree-walking plugin — the fs plugin, the buildfile provider, and the go provider. Patterns in this list apply everywhere at once, unlike per-plugin skip options which affect only one provider.

.hephconfig
fs:
skip:
- vendor # literal dir — pruned by every plugin
- "./node_modules" # leading ./ is normalized (same as "node_modules")
- "**/generated/**" # glob — prunes any dir named generated at any depth

Each entry is interpreted by its shape:

Entry shapeEffect
Literal path (no *, ?, [, {)Pruned by exact match against workspace-relative paths. ./-prefixed forms normalize to bare paths (./vendorvendor).
Glob pattern (contains metacharacters)Matched against workspace-relative paths using glob semantics.

.git is always ignored — you do not need to list it.

fs.skip vs per-plugin skip

The buildfile and go plugins each accept their own skip option (under options.skip on their respective plugins: entry). Those apply only to the respective plugin.

fs.skip is global: the engine merges it with every plugin's own skip list before building the final ignore set, so the same path is pruned consistently across every plugin.

Use fs.skip for workspace-wide exclusions (e.g. vendor, node_modules, generated output trees). Use per-plugin skip for patterns that should only affect one provider.

memCache — in-memory cache

Bounds the cache heph keeps in memory for the current run.

.hephconfig
memCache:
perEntryBytes: 16384 # largest single entry kept in memory
capacityBytes: 67108864 # total budget; 0 disables the in-memory cache

cache — local cache storage

Controls how heph stores artifacts in the durable on-disk cache.

.hephconfig
cache:
spillThresholdBytes: 8388608 # optional; default is 8 MiB
KeyTypeDefaultDescription
spillThresholdBytesnumber8388608 (8 MiB)Artifacts strictly larger than this are stored as plain files under <homeDir>/cache/blobs/. Smaller artifacts and all manifests stay in the cache database.

Raising the threshold keeps more artifacts in the database; lowering it spills more to plain files. The default works well for most projects.

caches — remote shared caches

A map of named remote caches. Each entry is keyed by a name you choose and describes one backend:

.hephconfig
caches:
shared:
uri: s3://my-bucket/heph-cache
read: true # default
write: true # default
concurrency: 10 # default

Multiple caches are allowed. heph writes to all writable caches in parallel and reads from the fastest first. Latency is measured once per process (or loaded from a persisted file) and refreshed when the definitions change.

KeyTypeDefaultDescription
uristringBackend URI. The scheme selects the backend (see table below).
readbooltrueWhether to consult this cache on a local miss.
writebooltrueWhether to push artifacts here after a local write. Writes happen on a background task — the build does not wait on the network.
concurrencynumber10Maximum in-flight requests to this cache at once.

Supported URI schemes:

SchemeBackendCredentials
s3://bucket/prefixAmazon S3 (and compatible)AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY, AWS_PROFILE, or instance role
gs://bucket/prefixGoogle Cloud StorageGOOGLE_APPLICATION_CREDENTIALS or ADC
az://container/prefixAzure Blob StorageAZURE_STORAGE_ACCOUNT_NAME + AZURE_STORAGE_ACCESS_KEY
https://host/prefixGeneric HTTP object store
file:///pathLocal filesystem

Run heph tool cache measure-latency to force a fresh latency measurement and print per-cache round-trip times. See the Remote cache guide for a complete walkthrough.

fuse — sandbox overlay

Controls whether sandboxes are assembled with a FUSE overlay instead of copying inputs. It is opt-in.

warning

The FUSE overlay is in development and not yet fully functional. Leave it off for production builds.

.hephconfig
fuse:
enabled: auto # true | false | auto
ValueBehavior
falseOff. The default when the block or key is omitted.
trueForced on.
autoThe engine decides per target.

See Sandbox for what the overlay changes.

lock — execute-phase lock backend

Selects how heph serializes concurrent access during execution.

.hephconfig
lock:
backend: fs # fs (default) | mem

fs coordinates across processes via the filesystem; mem keeps the lock in-process (useful for ephemeral or single-process runs).

telemetry — usage reporting

heph collects anonymous, aggregate usage data to guide development. No target addresses, file paths, labels, or any user-identifying information is ever reported — only coarse facts like OS, architecture, version, command name, aggregate counters (targets resolved, cache hits, artifact count), and an anonymous repo fingerprint.

Telemetry is on by default (opt-out). To disable it, add to .hephconfig:

.hephconfig
telemetry:
enabled: false

You can also opt out via environment variable, which takes precedence over the config file:

export HEPH_DISABLE_TELEMETRY=1

The environment variable is useful in CI pipelines or scripts where you do not want to touch the config file.

KeyTypeDefaultDescription
enabledtrue | falsetrueSet to false to disable all reporting.

Profiles — layered config overlays

Set the HEPH_PROFILES environment variable to a comma-separated list of profile names to layer additional config files on top of .hephconfig:

HEPH_PROFILES=ci heph run //...

For each name in the list, heph loads <name>.hephconfig from the workspace root and merges it over the accumulated config in order. HEPH_PROFILES=a,b loads the base .hephconfig, then applies a.hephconfig, then b.hephconfig — each merged over the result of the previous step.

A profile file that is missing or has invalid YAML is a hard error.

Merge rules

Config sectionBehavior
Scalar fields (homeDir, lock, fuse, telemetry, …)Profile value wins when present; base value is kept when absent.
cachesDeep-merged by cache name. A profile can patch individual fields (e.g. flip write) while inheriting the rest of the entry from the base.
pluginsMerged by identifier (builtin/path/url value). A matching entry is replaced in place; new ones are appended, preserving order.

Disabling remote cache writes locally

The base config enables a shared cache for everyone. A dev profile turns off writes so local machines read from the cache without polluting it:

.hephconfig
caches:
shared:
uri: s3://my-bucket/heph-cache
read: true
write: true
dev.hephconfig
caches:
shared:
write: false # inherit uri and read from the base
HEPH_PROFILES=dev heph run //...

CI-specific settings

A ci profile can override any key — here disabling telemetry and ensuring the shared cache is writable:

ci.hephconfig
telemetry:
enabled: false
caches:
shared:
write: true

Activate it in your workflow:

.github/workflows/build.yml
env:
HEPH_PROFILES: ci

See the CI guide for a full CI setup.