Skip to main content
Version: v5.7.0

opschain packs fetch

Included from Basic tier

opschain packs fetch [name ...]

Reads .opschain/packs.yaml in the current repository and resolves every declaration that names a git source — remote: or url: with rev: — into the local pack cache, or only the names given. Afterwards a local run mounts those packs from the cache with no network: the verb is the one deliberate fetch, and re-running it is how a branch rev: moves.

For each declaration:

  1. The source. url: is used as written. remote: names one of the repository's own git remotes (git remote -v) — the local twin of a server's project-configured remotes — and resolves to that remote's fetch URL. The fetch uses the git on your PATH with its credential helpers disabled (the engine's isolated git environment): a public remote, a file:// path or an SSH remote served by your agent works; a remote that needs an HTTPS credential helper does not.
  2. The rev. A branch or tag is fetched into the home's mirror of the remote and resolved to its current commit; a full commit SHA the mirror already holds resolves offline. The result is one exact commit.
  3. The tree is extracted into <opschain home>/packs/<name>/<sha> through a staging directory, so a half-written entry never serves a run. A commit already cached is kept (cached in the status column).
  4. The manifest. A pack manifest at the tree's repository root (.opschain/pack-manifest.json) is verified exactly as a signed bundle is — signature against the product keyring, then the entitlement it requires against the licence files in the home. A manifest that does not verify is refused by name and nothing is cached — stricter than a server, which runs such a pack ungated with a warning event — because a local fetch is a deliberate act and a pack whose signed identity does not verify should never land on disk unnoticed. A tree without a manifest is cached and runs ungated (unsigned).
  5. The index <opschain home>/packs/<name>/index.json records (source, rev) → sha, the mirror the step checkout materialises from and the verified manifest identity. A local run looks its declaration up there and refuses by name when it is missing.

At run time the mount re-verifies the cached manifest (signature and entitlement) before anything runs, reads the compile's action files from the cached tree, and materialises the step checkout from the mirror at the pinned commit — the same materialisation a server run uses. The path: key selects a pack root inside a monorepo, exactly as on a server. A pack's own .opschain/packs.yaml dependencies are not fetched transitively — declare each pack a local run needs in the repository's own file.

Output​

A table, one row per declaration fetched: NAME, SOURCE (credentials scrubbed), REV, SHA, MANIFEST (the verified pack identity, or unsigned), STATUS (fetched or cached) and CACHE (the tree's directory). -o json prints the same rows (name, source, rev, sha, path, cache_dir, manifest, fetched). A repository whose packs are all bundled, bundle: or installed: prints no git-sourced pack declarations (remote:/url:) to fetch.

Exit codes​

CodeMeaning
0Every selected declaration is in the cache.
1A declaration failed to resolve, verify or cache (nothing after it is fetched), or the command itself failed.

Named errors​

  • no .opschain/packs.yaml in <repo> — nothing to fetch ….
  • .opschain/packs.yaml declares no pack "<name>" (declared: …) — a name the file does not carry.
  • pack "<name>" resolves from <the release's bundled snapshot | the signed bundle file … | the installed pack store (…)> and needs no fetch — a named declaration that is not git-sourced.
  • pack "<name>": remote "<remote>" is not a git remote of <repo> … — remote: names no remote of the repository; add it with git remote add, or declare url:.
  • pack "<name>": rev "<rev>" does not match a Git revision (branch/tag/commit) in <source>.
  • pack "<name>": resolving rev "<rev>" in <source> failed: … — the fetch itself (network, authentication, host key), classified.
  • pack "<name>": its pack manifest (.opschain/pack-manifest.json) does not verify against the product keyring: … — refused; nothing cached.
  • The entitlement refusal — pack, entitlement and remedy — when a verified manifest requires a packs:<name> entitlement the home's licence files do not grant (opschain docs entitlements).
  • packs fetch is repo-scoped and runs locally — it has no remote form; run it in the repository (or pass --local) — a server target.

A local run that reaches an unfetched declaration fails before anything runs with pack "<name>" (<source> at <rev>) is not in the local pack cache — run opschain packs fetch once (it needs the network); local runs mount git-sourced packs from the cache only; a cache entry whose tree or mirror has been removed names the re-fetch the same way.

Examples​

Declare a pack by git source and fetch it once:

# .opschain/packs.yaml
packs:
- name: tools
url: https://github.com/example/opschain-pack-tools.git
rev: v1.4.0
opschain packs fetch
NAME SOURCE REV SHA MANIFEST STATUS CACHE
tools https://github.com/example/opschain-pack-tools.git v1.4.0 3f2a9c… unsigned fetched /home/alice/.opschain/packs/tools/3f2a9c…

Then run offline (opschain run tools:lint, with the environment flag as usual — opschain docs cli/run).

In CI, fetch in the job's first step and run in the next; a commit rev: already in the mirror resolves with no network at all.

See also​

  • opschain docs cli/packs — the family.
  • opschain docs pack-store — how a server resolves, pins and gates packs.
  • opschain learn 2.4, opschain learn 2.6.