Skip to content

Fetch Configs

When an app is taken from the queue, Holden fetches its configuration from git before reconciling.

Apps are registered in /data/apps.yml, each pointing to a git repo:

apps.yml
apps:
my-app:
repo: https://github.com/you/my-app
branch: main
path: ./

Holden uses git’s sparse checkout to fetch only holden.yml and holden.vars.yml from the app’s path—no other files are downloaded. This makes cloning fast regardless of repo size.

For monorepos, each app points to a different subdirectory:

apps.yml
apps:
frontend:
repo: https://github.com/you/monorepo
path: ./apps/frontend
backend:
repo: https://github.com/you/monorepo
path: ./apps/backend

Holden sparse-clones only apps/frontend/holden.yml and apps/frontend/holden.vars.yml for the frontend app, and similarly for the backend.

Repos are cloned to a temp directory, read, then deleted. No persistent cache.

For private repos, set an env var on the Holden container based on the git host:

HostEnv var
github.comGITHUB_PAT
gitlab.comGITLAB_PAT
bitbucket.orgBITBUCKET_PAT

If no env var is set, Holden clones without auth (works for public repos).

See Creating a GitHub PAT for step-by-step instructions.

If fetching fails (network error, auth failure, repo not found), Holden logs the error and moves on to the next queued app. The failed app will be retried when it’s next triggered (by polling, webhook, or maintenance).

One app’s git failure never blocks another app’s deployment.

When Holden boots, it queues all apps from apps.yml. For each app, Holden attempts to fetch its config.

If a repo doesn’t exist yet (you registered an app but haven’t created the repo), the fetch fails gracefully:

  1. Holden logs the error
  2. Moves on to the next app
  3. The missing app will be retried on the next trigger (poll timer, webhook, or maintenance)

This means you can register apps before their repos exist. Holden won’t crash—it just waits until the repo is available.