Skip to content

feat: ship npm artifacts alongside pnpm in the app template (2/3) - #598

Closed
atilafassina wants to merge 9 commits into
pnpm-template/1-pnpm-firstfrom
pnpm-template/2-npm-artifacts
Closed

atilafassina wants to merge 9 commits into
pnpm-template/1-pnpm-firstfrom
pnpm-template/2-npm-artifacts

Conversation

@atilafassina

Copy link
Copy Markdown
Contributor

What & why

Phase 2 of the pnpm-first app-template initiative (stacked on #593). Restores first-class npm support so a scaffold selected as npm (databricks apps init --package-manager npm) installs and deploys with native deps intact, while the committed default stays pnpm-shaped. Both lockfiles ship and both are leak-validated in CI, fail-closed.

Stacked PR — base is pnpm-template/1-pnpm-first (#593), not main. Review only the commits above #593.

Changes

npm artifacts (template/)

Dual-lock validation + CI

  • check-template-lock-registry validates both pnpm-lock.yaml and package-lock.json by default, fail-closed if either is missing; the pnpm handler now parses YAML (tarball / git / directory / missing resolutions fail closed, at parity with the npm handler)
  • new npm deploy-shape smoke coverage: bare npm install on linux-x64, assert @ast-grep/napi-linux-x64-gnu materializes + loads at runtime, build client & server (runtime-load check added to the pnpm path too)
  • artifact/smoke logic extracted into shared tools/template-artifacts.ts + tools/template-smoke-runner.ts with a template-artifacts.test.ts suite
  • pr-template-artifact regenerates both locks against the PR tarballs and rewrites/validates both before zipping, so the artifact no longer ships a stale pnpm-lock.yaml

Testing

  • pnpm build, pnpm -r typecheck, pnpm check, pnpm test, check-template-lock-registry, check-template-deps — all green.
  • The linux-x64 native-binary materialization is exercised by the CI smoke job on a linux runner (not reproducible locally on darwin).

Notes

This pull request and its description were written by Isaac.

atilafassina and others added 8 commits September 23, 2026 14:48
Flip the `databricks apps init` app template from npm to pnpm as the
default package manager so scaffolds deploy to Databricks Apps with
native deps intact.

- ship template/pnpm-lock.yaml (pnpm@11.0.8) plus a single-app
  pnpm-workspace.yaml carrying the migrated overrides, allowBuilds
  (esbuild, @ast-grep/napi, ...) and supportedArchitectures for
  linux/x64/glibc, so @ast-grep/napi-linux-x64-gnu materializes on install
- set packageManager to pnpm@11.0.8 and make every script sibling call an
  explicit `pnpm run <script>` (pnpm 11 shadows bare `pnpm <script>`)
- enable pre/post scripts via template/.npmrc so prebuild (typegen) fires
- render app.yaml `command: ['pnpm', 'run', 'start']`; template README to pnpm
- validate template/pnpm-lock.yaml in the leak validator (format-dispatch by
  filename) and drop the npm package-lock.json (returns in Phase 2)

Co-authored-by: Isaac <no-reply@databricks.com>
Signed-off-by: Atila Fassina <atila@fassina.eu>
Guard the deploy shape the pnpm-first template depends on: a fresh
`pnpm install --frozen-lockfile` on the scaffolded app must materialize
the linux native dep and run its build.

- tools/smoke-test-template.ts scaffolds the committed template into
  .smoke-test/app (renders the mustache placeholders, no tarball
  rewrite) so the frozen install runs against the committed pnpm-lock
- new `template-deploy-shape` CI job installs --frozen-lockfile on
  linux-x64, asserts @ast-grep/napi-linux-x64-gnu materialized, and runs
  build:client/build:server (typegen/boot need a live workspace, so are
  out of CI scope)
- gitignore the .smoke-test scratch dir and exclude it from oxlint/oxfmt

This closes the long-standing deploy-shape CI gap; it caught the
allowBuilds mis-encoding fixed in the previous commit.

Co-authored-by: Isaac <no-reply@databricks.com>
Signed-off-by: Atila Fassina <atila@fassina.eu>
Signed-off-by: Atila Fassina <atila@fassina.eu>
Co-authored-by: Isaac <no-reply@databricks.com>
Signed-off-by: Atila Fassina <atila@fassina.eu>
Co-authored-by: Isaac <no-reply@databricks.com>
Signed-off-by: Atila Fassina <atila@fassina.eu>
Co-authored-by: Isaac <no-reply@databricks.com>
Bring back first-class npm support in the pnpm-first app template so a
scaffold selected as npm (`databricks apps init --package-manager npm`)
installs and deploys with native deps intact. The committed default stays
pnpm-shaped.

- ship template/package-lock.json (lockfileVersion 3, public registry only)
- re-add top-level npm `overrides` in template/package.json, mirroring the
  pnpm-workspace.yaml overrides
- pin @ast-grep/napi-linux-x64-gnu as a root optionalDependency (os/cpu
  guarded by the package itself) as a defensive edge against npm/cli#4828
  style lock regeneration dropping the linux binary; regenerate
  pnpm-lock.yaml for the new edge
- check-template-deps: fail when the npm and pnpm override placements
  drift, or when the linux pin is missing or skews from @ast-grep/napi

Co-authored-by: Isaac <no-reply@databricks.com>
Signed-off-by: Atila Fassina <atila@fassina.eu>
- check-template-lock-registry validates template/pnpm-lock.yaml and
  template/package-lock.json by default, fail-closed if either is missing
- parse pnpm-lock.yaml with `yaml` instead of a URL regex so tarball, git,
  directory and missing resolutions fail closed, at parity with the npm
  handler; the npm handler now fails on non-root/link/bundled entries with
  no `resolved`; each .npmrc is checked once
- add template-deploy-shape-npm: bare `npm install` from the committed lock
  on linux-x64, assert @ast-grep/napi-linux-x64-gnu materializes and loads,
  build client and server
- load @ast-grep/napi at runtime in the pnpm deploy-shape job too
- smoke-test-template: --package-manager selects which lock the scaffold keeps
- pr-template-artifact regenerates both locks against the PR tarballs
  (npm install, then pnpm install --lockfile-only) and rewrites and
  validates both before zipping, so the artifact no longer ships a stale
  pnpm-lock.yaml

Co-authored-by: Isaac <no-reply@databricks.com>
Signed-off-by: Atila Fassina <atila@fassina.eu>
Signed-off-by: Atila Fassina <atila@fassina.eu>
Copilot AI lite review requested due to automatic review settings September 23, 2026 18:54
@atilafassina
atilafassina requested a review from a team as a code owner September 23, 2026 18:54
@atilafassina
atilafassina requested review from MarioCadenas and removed request for a team September 23, 2026 18:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Unresolved lockfile validation, release-artifact regeneration, and Windows path portability issues remain.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 2 Medium severity

Open (3)
What changed in this PR

Restores npm support alongside pnpm for the app template, including dual lockfiles, native dependency handling, artifact generation, and CI smoke coverage.

Changes:

  • Adds npm overrides, lockfile support, and native dependency pinning.
  • Expands lockfile validation and package-manager smoke tests.
  • Updates template generation, artifacts, documentation, and CI.
File Summary
vitest.config.ts Adds tooling test coverage.
tools/​template-smoke-runner.ts Runs npm and pnpm install, build, and runtime checks.
tools/​template-artifacts.ts Manages package-manager artifacts.
tools/​template-artifacts.test.ts Tests artifact behavior.
tools/​smoke-test-template.ts Adds package-manager smoke options; Windows path portability issue remains.
tools/​prepare-template-artifact.ts Prepares release artifacts; dual-lock regeneration and registry rewriting need correction.
tools/​generate-app-templates.ts Preserves package-manager files in generated templates.
tools/​check-template-lock-registry.ts Validates npm and pnpm registries; malformed or missing package maps can currently pass.
tools/​check-template-deps.ts Checks override and native dependency parity.
tools/​check-template-artifact.ts Validates bundled dependency resolutions.
template/​README.md.tmpl Documents package-manager commands.
template/​pnpm-workspace.yaml Updates pnpm configuration.
template/​pnpm-lock.yaml Records native dependency resolution.
template/​package.json Adds npm overrides and native optional dependency pinning.
template/​app.yaml.tmpl Selects package-manager startup behavior.
pnpm-lock.yaml Locks tooling dependencies.
package.json Adds YAML tooling dependency.
docs/​docs/​development/​templates.md Documents package-manager templating.
.github/​workflows/​ci.yml Adds dual package-manager smoke and artifact validation.
Files not reviewed (2)
  • pnpm-lock.yaml: Generated file
  • template/pnpm-lock.yaml: Generated file

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +123 to +130
const workspacePath = join(STAGING_DIR, "pnpm-workspace.yaml");
const workspace = parseDocument(readFileSync(workspacePath, "utf-8"));
if (workspace.errors.length) throw workspace.errors[0];
workspace.setIn(
["overrides", "@databricks/lakebase"],
pkg.overrides["@databricks/lakebase"],
);
writeFileSync(workspacePath, workspace.toString());
Comment thread tools/check-template-lock-registry.ts Outdated
Comment on lines +239 to +248
const yamlStr = readFileSync(path, "utf-8");
const lockfile = parseYaml(yamlStr) as Record<string, unknown>;

const packages: Record<
string,
{ resolution?: Record<string, unknown> | string }
> = (lockfile.packages ?? {}) as Record<
string,
{ resolution?: Record<string, unknown> | string }
>;
Comment thread tools/check-template-lock-registry.ts Outdated
Comment on lines +289 to +293
// If there's no type and no tarball, it must be registry-derived (integrity only)
if (!res.tarball) {
// Registry-derived resolutions have only integrity, which is OK
continue;
}
@github-actions

github-actions Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

🤖 AppKit PR bot

🔬 Run evals

Start an eval for this PR from the evals-monitor app: Go to Evals Monitor →

📦 Try this PR's app template

Scaffolds a new app from this PR's SDK build. Run it in any folder (requires the GitHub CLI — gh auth login — and the Databricks CLI):

gh run download 35978478952 -R databricks/appkit -n appkit-template-0.76.1-pr.23f8611-pnpm-template-2-npm-artifacts-598 -D appkit-pr-598 \
  && unzip -o "appkit-pr-598/appkit-template-0.76.1-pr.23f8611-pnpm-template-2-npm-artifacts-598.zip" -d "appkit-pr-598" \
  && databricks apps init --template "appkit-pr-598"

The template pins @databricks/appkit and @databricks/appkit-ui to tarballs built from this branch, so the scaffolded app runs against this PR's code.

Signed-off-by: Atila Fassina <atila@fassina.eu>
@atilafassina
atilafassina marked this pull request as ready for review September 25, 2026 10:36
Comment thread template/package.json
"test": "vitest run",
"clean": "rm -rf client/dist dist build node_modules",
"prebuild": "pnpm run sync && pnpm run typegen --wait",
"prebuild": "pnpm run sync && appkit generate-types --wait",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we change this one?

@atilafassina

Copy link
Copy Markdown
Contributor Author

Superseded by #593 — the pnpm-template stack has been consolidated into a single PR targeting main (all 11 commits, phases 1–3, rebased onto latest main). Closing this one; the review thread history stays here for reference.

This comment was written by Isaac.

An error occurred while trying to automatically change base from pnpm-template/1-pnpm-first to main October 1, 2026 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants