From f43e41427793b9b02f414f395c42f3ca934424df Mon Sep 17 00:00:00 2001 From: Atila Fassina Date: Fri, 31 Jul 2026 14:52:53 +0200 Subject: [PATCH 1/2] docs: document committed .appkit/ type cache and warehouse-less deploys Reflect the typegen cache relocation in the docs: - type-generation.md: add a "Type cache" section (cache now lives in the committed .appkit/ dir, not node_modules; what to commit; deterministic serialization) and a "Deploying without warehouse access" subsection covering the rollout ordering (seed + commit .appkit/ while the warehouse is reachable, then cut access) and the bootstrap-vs-drift failure messages. Update the --wait section to describe hit-skips-warehouse / miss-attempts / unresolved-miss-fails semantics. - project-setup.md: add .appkit/ to the canonical layout as a committed artifact (do not gitignore). - app-management.mdx: deploy-guide admonition that a warehouse-less deploy needs a committed .appkit/ covering every query. Co-authored-by: Isaac Signed-off-by: Atila Fassina --- docs/docs/app-management.mdx | 6 ++++++ docs/docs/development/project-setup.md | 1 + docs/docs/development/type-generation.md | 22 +++++++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/docs/docs/app-management.mdx b/docs/docs/app-management.mdx index 4aeffebba..5369783d2 100644 --- a/docs/docs/app-management.mdx +++ b/docs/docs/app-management.mdx @@ -42,6 +42,12 @@ databricks apps deploy --help ``` ::: +:::info Type cache and warehouse-less deploys + +The build step runs type generation in blocking mode. If your deploy pipeline cannot reach a SQL warehouse, the build still succeeds **only if the committed `.appkit/` type cache covers every query** — otherwise it fails rather than shipping degraded types. Commit `.appkit/` while the warehouse is still reachable, before removing warehouse access from CI/CD. See [Type generation → Deploying without warehouse access](./development/type-generation.md#deploying-without-warehouse-access). + +::: + ### Examples - Deploy to a specific target: diff --git a/docs/docs/development/project-setup.md b/docs/docs/development/project-setup.md index 8aea2e14c..97d5fb2b8 100644 --- a/docs/docs/development/project-setup.md +++ b/docs/docs/development/project-setup.md @@ -24,6 +24,7 @@ my-app/ ├── config/ │ └── queries/ │ └── my_query.sql +├── .appkit/ # committed type cache (do NOT gitignore) ├── app.yaml ├── package.json └── tsconfig.json diff --git a/docs/docs/development/type-generation.md b/docs/docs/development/type-generation.md index 04b2091c6..1bdc315ad 100644 --- a/docs/docs/development/type-generation.md +++ b/docs/docs/development/type-generation.md @@ -82,7 +82,27 @@ Pass `--wait` for CI and production builds, where accurate types must be present npx @databricks/appkit generate-types --wait ``` -In blocking mode the generator starts a stopped warehouse, waits (bounded) for it to reach `RUNNING`, and then describes your queries. It fails only when the configured warehouse no longer exists (deleted/deleting), so a transient outage or a cold warehouse degrades gracefully rather than breaking the build. The app template wires this up for you: `postinstall` and `predev` run the non-blocking default, while `prebuild` runs `--wait`. +In blocking mode the generator skips the warehouse entirely for any query whose types are already in the [type cache](#type-cache) (a cache **hit** makes zero warehouse round-trips). Only a cache **miss** contacts the warehouse: it starts a stopped warehouse, waits (bounded) for it to reach `RUNNING`, and then describes the query. A miss that cannot be resolved to a real type — a deleted warehouse, or (see below) a CI environment with no warehouse access — **fails the build** rather than shipping `result: unknown`. A transient connectivity blip still degrades gracefully. The app template wires this up for you: `postinstall` and `predev` run the non-blocking default, while `prebuild` runs `--wait`. + +## Type cache + +Type generation is backed by a per-app cache so that unchanged queries never pay for a repeat `DESCRIBE`. The cache lives in a committed `.appkit/` directory at your app root: + +- `.appkit/types-cache.json` — query and metric-view DESCRIBE results +- `.appkit/serving-types-cache.json` — model-serving endpoint schemas + +**`.appkit/` is a committed build artifact — check it into git; do not add it to `.gitignore`.** Committing it is what lets a blocking (`--wait`) build succeed with **no warehouse access**: on a fresh `git checkout` + `pnpm install`, every query is already a cache hit, so the build makes zero warehouse round-trips. (Ephemeral coordination state — a background-worker lock and the UI-variant choices file — stays under `node_modules/.databricks/appkit/` and is *not* committed.) + +The cache serializes deterministically (top-level keys sorted), so a no-op regeneration produces a no-op diff and unrelated query changes don't collide in merges. + +### Deploying without warehouse access + +If your CI/CD environment cannot reach a SQL warehouse (for example, an authorization boundary removes warehouse access from the deploy pipeline), a blocking build still works **as long as the committed `.appkit/` cache covers every query** — all hits, no warehouse needed. + +This imposes a rollout ordering: **produce and commit `.appkit/` while the warehouse is still reachable, then remove warehouse access.** A build that runs after warehouse access is gone with an uninitialized or incomplete cache fails loudly (never silently degrades to `unknown`), and the error message tells you which case you hit: + +- **Uninitialized cache** (no `.appkit/` yet) — run `generate-types --wait` against a warehouse and commit `.appkit/`. +- **Drifted cache** (a query changed since the cache was built) — regenerate the affected query against a warehouse and commit the updated `.appkit/`. ## Metric-view types From a0a5c38785729051801f4fbfb03b5a9e9053600d Mon Sep 17 00:00:00 2001 From: Atila Fassina Date: Fri, 31 Jul 2026 16:35:00 +0200 Subject: [PATCH 2/2] docs: match typegen cache-failure labels to actual CLI messages Align the warehouse-less deploy failure bullets with the strings the build actually prints ('No committed type cache found' vs 'The committed .appkit/ cache is missing or stale') so they are greppable in CI logs, and broaden the drift case to cover added/missing queries, not just changed ones. Co-authored-by: Isaac Signed-off-by: Atila Fassina --- docs/docs/development/type-generation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/development/type-generation.md b/docs/docs/development/type-generation.md index 1bdc315ad..94199cd6e 100644 --- a/docs/docs/development/type-generation.md +++ b/docs/docs/development/type-generation.md @@ -101,8 +101,8 @@ If your CI/CD environment cannot reach a SQL warehouse (for example, an authoriz This imposes a rollout ordering: **produce and commit `.appkit/` while the warehouse is still reachable, then remove warehouse access.** A build that runs after warehouse access is gone with an uninitialized or incomplete cache fails loudly (never silently degrades to `unknown`), and the error message tells you which case you hit: -- **Uninitialized cache** (no `.appkit/` yet) — run `generate-types --wait` against a warehouse and commit `.appkit/`. -- **Drifted cache** (a query changed since the cache was built) — regenerate the affected query against a warehouse and commit the updated `.appkit/`. +- **`No committed type cache found`** (no `.appkit/` yet) — run `generate-types --wait` against a warehouse and commit `.appkit/`. +- **`The committed .appkit/ cache is missing or stale`** (a query was added or changed since the cache was built, or its entry is missing) — regenerate against a warehouse and commit the updated `.appkit/`. ## Metric-view types