Repository navigation
feat: let apps init render the package manager in scripts - #632
atilafassina wants to merge 1 commit into
Conversation
The build, prebuild, and predev scripts hardcoded `pnpm run`, so the Databricks CLI had to parse and rewrite shell commands in package.json when a user picked npm. Use the same `or .packageManager "pnpm"` expression as app.yaml.tmpl and README.md.tmpl so `databricks apps init` renders the selected manager directly. CLIs that don't pass packageManager still get pnpm. package.json is parsed as JSON before rendering (by the CLI and by our tooling), so the expression uses a backtick string literal instead of double quotes. The smoke fixture now renders the placeholder instead of rewriting `pnpm run` to `npm run`, and a new test fails if a template script hardcodes a package manager. Co-authored-by: Isaac <no-reply@databricks.com> Signed-off-by: Atila Fassina <atila@fassina.eu>
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The focused changes preserve existing defaults and include appropriate npm and pnpm coverage.
Review effort: Balanced
Findings: None
What changed in this PR
Makes generated app scripts use the package manager selected by databricks apps init, defaulting to pnpm.
Changes:
- Adds a reusable package-manager template placeholder.
- Updates build lifecycle scripts to render npm or pnpm.
- Adds tests preventing hardcoded package managers.
| File | Description |
|---|---|
template/package.json |
Makes build scripts package-manager-aware. |
tools/template-smoke-runner.ts |
Renders package-manager placeholders in smoke fixtures. |
tools/template-artifacts.test.ts |
Tests script portability and placeholder usage. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
🤖 AppKit PR bot🔬 Run evalsStart an eval for this PR from the evals-monitor app: Go to Evals Monitor → 📦 Try this PR's app templateScaffolds a new app from this PR's SDK build. Run it in any folder (requires the GitHub CLI — gh run download 37494079840 -R databricks/appkit -n appkit-template-0.82.0-pr.9451617-template-pm-scripts-632 -D appkit-pr-632 \
&& unzip -o "appkit-pr-632/appkit-template-0.82.0-pr.9451617-template-pm-scripts-632.zip" -d "appkit-pr-632" \
&& databricks apps init --template "appkit-pr-632"The template pins |
Summary
template/package.jsonhardcodespnpm runinbuild,prebuild, andpredev. Because of that,databricks apps init --package-manager npmhas to parse and rewrite shell commands in package.json (libs/apps/pkgmanager/scripts.goin databricks/cli#6902).This PR uses the same expression that
app.yaml.tmplandREADME.md.tmplalready use (#593), so the CLI renders the selected manager:Once this ships in
template-v0.82.0, the CLI only needs to setnameandpackageManagerin package.json, andscripts.go/scripts_test.gocan be deleted. This was suggested in the review of databricks/cli#6902. It needs to merge beforetemplate-v0.82.0is tagged.Notes
"pnpm": package.json is parsed as JSON before it's rendered, by the CLI's background install and byprepare-template-artifact.ts,check-template-deps.ts, andtemplate-artifacts.ts. Double quotes would make the raw file invalid JSON. Go'stext/templatetreats`pnpm`and"pnpm"the same.packageManagerrender the default,pnpm. I checked withtext/template+missingkey=zero: no key →pnpm run …,npm→npm run …,pnpm→pnpm run ….generate-app-templates.tsalready copies the raw templatescriptsback over the rendered ones (preservePackageManagerArtifacts). The placeholder survives into the published variant, and the user's finalapps initrenders it.CI against the un-rendered template
I checked every path that runs on raw
template/or its copies:pr-template-artifact(ci.yml) andprepare-release.ymlrunnpm install,pnpm install --lockfile-only, andnpm test(vitest run). None of them invokepnpm run, and the template has no install lifecycle scripts. These only need the file to be valid JSON, which it still is.template-deploy-shape/template-deploy-shape-npmrunpnpm/npm run build. They go throughselectSmokePackageManager, which now renders the placeholder for both managers instead of rewritingpnpm run→npm run.%s prebuild runs syncunit test runsprebuilddirectly and uses the same helper.A new test fails if a template script hardcodes
npm/pnpm/yarn/bun. Once the CLI stops rewriting scripts, a straypnpm runwould otherwise make npm apps call pnpm at build time. Againstorigin/mainit flagsbuild,prebuild, andpredev.Test plan
pnpm exec vitest run --project tools(63 passed)tsx tools/smoke-test-template.ts --package-manager npm --run: install,npm ci, build with prebuild, health check, client serving. The runner's fakepnpmon PATH was never called.tsx tools/smoke-test-template.ts --package-manager pnpm --run: same checks with pnpmThis pull request and its description were written by Isaac.