Pre-release Harn is pre-1.0 — the language, standard library, and CLI may change between releases. See the release notes

Bootstrap an exact Harn release

scripts/bootstrap_harn.mjs is Harn's supported host-native bootstrap interface for local development and CI systems outside GitHub Actions. It uses only Node.js built-ins, runs on Linux, macOS, and Windows, and never requires a POSIX shell. Node.js 20 or newer is required.

Pin the bootstrap script itself by checking out an immutable Harn release or commit, then provide either an exact version or a file containing one:

node path/to/harn/scripts/bootstrap_harn.mjs --version 0.10.31 --cache-dir path/to/cache --install-dir path/to/tools/harn
node path/to/harn/scripts/bootstrap_harn.mjs --version-file .harn-version --cache-dir path/to/cache --install-dir path/to/tools/harn

The effective request must resolve to one MAJOR.MINOR.PATCH value, with an optional leading v. latest, version ranges, and prerelease selectors are rejected. When neither option is written on the command line, --version-file defaults to .harn-version in the working directory; a missing or invalid file is a closed failure.

The command prints one JSON receipt to standard output:

{
  "schema_version": "harn-bootstrap-v1",
  "version": "0.10.31",
  "target": "aarch64-apple-darwin",
  "binary_path": "/ci/tools/harn/harn",
  "source": "https://github.com/burin-labs/harn/releases/download/v0.10.31/harn-aarch64-apple-darwin.tar.gz",
  "checksum": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
  "cache_hit": false,
  "binary_sha256": "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"
}

The first seven fields form the stable harn-bootstrap-v1 contract. binary_sha256 provides additional local integrity evidence. The installed directory also contains the integrity-only install-manifest.json used to validate future reuse; the JSON printed for each invocation is its audit receipt.

Verification and atomicity

Every online run downloads the exact release's SHA256SUMS, requires one unambiguous entry for the selected platform archive, and verifies the archive before extraction. A cached archive is only a candidate: the bootstrapper hashes it again against the release metadata before reporting cache_hit: true. If checksum metadata previously cached for an exact release differs from newly published metadata, the run fails closed.

Archive files and install directories are prepared beside their destinations and published atomically only after verification. Interrupted temporary paths never become cache or install state. Concurrent processes installing the same version may both do work, but they converge on one complete, validated installation; a process that loses publication validates the winner before returning.

The default cache is under the runner tool cache, $XDG_CACHE_HOME, Windows %LOCALAPPDATA%, or the user's .cache directory. The default installation is versioned below that bootstrap cache. Use --cache-dir and --install-dir in shared CI so Harn does not write to a package manager, Cargo home, or another toolchain's directory.

Offline runs

After one successful online install, --offline requires both of these exact version entries:

  • metadata/<version>/SHA256SUMS
  • downloads/<version>/<platform archive>

Offline mode performs no network request and re-hashes the archive against the cached checksum metadata. A missing or corrupt entry is a closed failure; the bootstrapper never selects another version or falls back to an unverified binary.

Proxies

The bootstrapper uses Node's built-in fetch. Node.js 22.21+, 24.5+, and newer release lines can read proxy settings when NODE_USE_ENV_PROXY=1 is set before Node starts. Configure HTTPS_PROXY, HTTP_PROXY, and NO_PROXY in the process environment. Harn's setup action enables this support automatically when the runner's Node version provides it. On older Node versions, use a network environment that provides direct GitHub access or pre-populate the exact cache on a connected machine and run with --offline.

Failure recovery and source builds

Rerun the same command after a network interruption. Unique .harn-bootstrap-* leftovers are ignored and can be deleted after no bootstrap processes are active. If an operator must rebuild one entry, remove only that version's metadata/archive directory and its versioned install directory, then rerun online.

The bootstrapper does not silently build from source. A source build has different provenance, prerequisites, and cache semantics, so it must be an explicit policy decision. The supported fallback is to install the same exact version with Rust:

cargo install --locked harn-cli --version 0.10.31

Alternatively, check out the matching v0.10.31 source tag and run cargo install --locked --path crates/harn-cli. Neither source-build path emits a harn-bootstrap-v1 receipt or counts as a release-archive cache hit.

GitHub Actions

The first-party setup action is a thin adapter over this same file. It resolves the version and platform through the bootstrapper, restores the candidate cache, invokes the bootstrapper for verification and installation, adds the binary directory to PATH, and exposes the JSON as its receipt output:

- uses: burin-labs/harn/.github/actions/setup-harn@<full-commit-sha>
  id: harn
  with:
    version: 0.10.31
- env:
    HARN_RECEIPT: ${{ steps.harn.outputs.receipt }}
  run: node -e 'process.stdout.write(process.env.HARN_RECEIPT)'