Repository navigation
docs: design 002, database route operations #2969
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| # No base-branch filter: stacked PRs (base = the PR below them) get CI too. | |
| pull_request: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| id-token: write | |
| jobs: | |
| detect-changes: | |
| runs-on: | |
| group: databricks-ghec-untrusted-runner-group | |
| labels: linux-ubuntu-latest-untrusted-2core-8gb | |
| name: Detect Changes | |
| outputs: | |
| docs: ${{ steps.filter.outputs.docs }} | |
| appkit: ${{ steps.filter.outputs.appkit }} | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 | |
| id: filter | |
| with: | |
| filters: | | |
| docs: | |
| - 'docs/**' | |
| - 'packages/**' | |
| appkit: | |
| - '!docs/**' | |
| lint_and_typecheck: | |
| name: Lint & Type Check | |
| runs-on: | |
| group: databricks-ghec-untrusted-runner-group | |
| labels: linux-ubuntu-latest-untrusted-2core-8gb | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Setup JFrog npm | |
| uses: ./.github/actions/setup-jfrog-npm | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: .nvmrc | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Check generated types are up to date | |
| run: | | |
| pnpm run generate:types | |
| if ! git diff --exit-code \ | |
| packages/appkit/src/registry/types.generated.ts \ | |
| packages/appkit/src/plugins/ga-exports.generated.ts \ | |
| packages/appkit/src/plugins/beta-exports.generated.ts \ | |
| docs/static/schemas/plugin-manifest.schema.json \ | |
| docs/static/schemas/template-plugins.schema.json \ | |
| docs/docs/plugins/analytics.md \ | |
| docs/docs/plugins/files.md \ | |
| docs/docs/plugins/genie.md \ | |
| docs/docs/plugins/jobs.md \ | |
| docs/docs/plugins/lakebase.md \ | |
| docs/docs/plugins/model-serving.md \ | |
| docs/docs/plugins/server.md \ | |
| docs/docs/plugins/ai-search.md; then | |
| echo "❌ Error: Generated files are out of sync with their source manifests/schemas." | |
| echo "" | |
| echo "To fix this:" | |
| echo " 1. Run: pnpm run generate:types" | |
| echo " 2. Review and commit the changes" | |
| echo "" | |
| exit 1 | |
| fi | |
| - name: Build shared package dist (for sync:template CLI) | |
| # `pnpm run sync:template` runs through `packages/shared/bin/appkit.js` | |
| # which imports the built `packages/shared/dist/cli/index.js`. The | |
| # lint job doesn't otherwise build, so build just shared's dist | |
| # before invoking sync. | |
| run: pnpm --filter shared exec tsdown --config tsdown.config.ts | |
| - name: Check synced template manifest is up to date | |
| run: | | |
| pnpm run sync:template | |
| if ! git diff --exit-code template/appkit.plugins.json; then | |
| echo "❌ Error: template/appkit.plugins.json is out of sync with packages/appkit/src/plugins/<name>/manifest.json." | |
| echo "" | |
| echo "This usually happens when a plugin manifest's stability, resources, or display fields" | |
| echo "are edited without running the sync step that regenerates the template manifest." | |
| echo "" | |
| echo "To fix this:" | |
| echo " 1. Run: pnpm run sync:template" | |
| echo " 2. Review and commit the changes" | |
| echo "" | |
| exit 1 | |
| fi | |
| - name: Run Biome Check | |
| run: pnpm run check | |
| - name: Run Types Check | |
| run: pnpm run typecheck | |
| - name: Run Knip Check | |
| run: pnpm run knip | |
| - name: Run License Check | |
| run: pnpm run check:licenses | |
| - name: Check template deps are pinned | |
| run: pnpm exec tsx tools/check-template-deps.ts | |
| - name: Check template lockfile uses only public npm registry | |
| run: pnpm exec tsx tools/check-template-lock-registry.ts | |
| test: | |
| name: Unit Tests | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.appkit == 'true' | |
| runs-on: | |
| group: databricks-ghec-untrusted-runner-group | |
| labels: linux-ubuntu-latest-untrusted-2core-8gb | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Setup JFrog npm | |
| uses: ./.github/actions/setup-jfrog-npm | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: .nvmrc | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Run Tests | |
| run: pnpm test | |
| playground-integration-test: | |
| name: Playground Integration Tests | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.appkit == 'true' | |
| runs-on: | |
| group: databricks-ghec-untrusted-runner-group | |
| labels: linux-ubuntu-latest-untrusted-2core-8gb | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Setup JFrog npm | |
| uses: ./.github/actions/setup-jfrog-npm | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: .nvmrc | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Install Playwright Browsers | |
| run: pnpm --filter=dev-playground exec playwright install --with-deps chromium | |
| - name: Build packages | |
| run: pnpm build | |
| # The generated database registry must reach appkit-ui's built declarations. | |
| - name: Typecheck database components | |
| run: pnpm --filter=dev-playground typecheck:database | |
| - name: Run Integration Tests | |
| run: pnpm --filter=dev-playground test:integration | |
| env: | |
| APPKIT_E2E_TEST: 'true' | |
| DATABRICKS_WAREHOUSE_ID: e2e-mock | |
| DATABRICKS_WORKSPACE_ID: e2e-mock | |
| DATABRICKS_SERVING_ENDPOINT_NAME: e2e-mock | |
| template-deploy-shape: | |
| name: Template Deploy-Shape (pnpm install, build, and startup) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.appkit == 'true' | |
| runs-on: | |
| group: databricks-ghec-untrusted-runner-group | |
| labels: linux-ubuntu-latest-untrusted-2core-8gb | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Setup JFrog npm | |
| uses: ./.github/actions/setup-jfrog-npm | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: .nvmrc | |
| cache: 'pnpm' | |
| - name: Install tooling dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Install, build, and start the pnpm template | |
| run: pnpm exec tsx tools/smoke-test-template.ts --package-manager pnpm --output-dir .smoke-test/app-pnpm --run | |
| template-deploy-shape-npm: | |
| name: Template Deploy-Shape (npm install, build, and startup) | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.appkit == 'true' | |
| runs-on: | |
| group: databricks-ghec-untrusted-runner-group | |
| labels: linux-ubuntu-latest-untrusted-2core-8gb | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Setup JFrog npm | |
| uses: ./.github/actions/setup-jfrog-npm | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: .nvmrc | |
| cache: 'pnpm' | |
| - name: Install tooling dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Install, build, and start the npm template | |
| run: pnpm exec tsx tools/smoke-test-template.ts --package-manager npm --output-dir .smoke-test/app-npm --run | |
| pr-template-artifact: | |
| name: PR Template Artifact | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.appkit == 'true' | |
| runs-on: | |
| group: databricks-ghec-untrusted-runner-group | |
| labels: linux-ubuntu-latest-untrusted-2core-8gb | |
| # Job-level permissions REPLACE (not merge with) the top-level set, so all | |
| # three must be listed: pull-requests: write for the sticky comment step, | |
| # and id-token: write which setup-jfrog-npm needs for its OIDC token. | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Setup JFrog npm | |
| uses: ./.github/actions/setup-jfrog-npm | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: .nvmrc | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Set PR version | |
| id: version | |
| env: | |
| BRANCH: ${{ github.head_ref }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| run: | | |
| SANITIZED_BRANCH=$(echo "$BRANCH" | sed 's/[^a-zA-Z0-9-]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//') | |
| SHORTSHA=$(git rev-parse --short HEAD) | |
| CURRENT_VERSION=$(node -p "require('./packages/appkit/package.json').version") | |
| PR_VERSION="${CURRENT_VERSION}-pr.${SHORTSHA}-${SANITIZED_BRANCH}-${PR_NUMBER}" | |
| echo "version=$PR_VERSION" >> "$GITHUB_OUTPUT" | |
| - name: Build SDK tarballs | |
| run: pnpm pack:prerelease | |
| # pnpm-patched dependencies are shipped inside the tarballs via | |
| # bundledDependencies (tools/bundle-patched-deps.ts). Install each tarball | |
| # with npm and pnpm and fail if a consumer would resolve an unpatched copy. | |
| - name: Verify bundled patched dependencies | |
| run: pnpm exec tsx tools/verify-bundled-patches.ts packages/appkit packages/appkit-ui | |
| - name: Prepare template artifact | |
| run: pnpm exec tsx tools/prepare-template-artifact.ts | |
| # Regenerate both lockfiles: the prepare-template-artifact script rewrites | |
| # package.json deps to file: references (local tarballs), which invalidates | |
| # the committed locks. We regenerate here under the JFrog .npmrc (set up | |
| # by setup-jfrog-npm), which bakes JFrog URLs into the locks; the rewrite | |
| # step below fixes that to point back to public npm. | |
| - name: Regenerate template lockfiles (npm and pnpm) | |
| working-directory: pr-template | |
| run: | | |
| echo "Regenerating package-lock.json..." | |
| npm install | |
| echo "✓ Regenerated package-lock.json and node_modules" | |
| echo "Regenerating pnpm-lock.yaml (lockfile-only to skip node_modules rebuild)..." | |
| # --no-frozen-lockfile allows regeneration even though the committed lock is now stale | |
| # (prepare-template-artifact rewrote package.json deps to file: references). | |
| # --lockfile-only skips rebuilding node_modules over npm's install above. | |
| pnpm install --lockfile-only --no-frozen-lockfile | |
| echo "✓ Regenerated pnpm-lock.yaml" | |
| - name: Verify bundled SDKs in both template locks | |
| run: pnpm exec tsx tools/check-template-artifact.ts pr-template | |
| # The scaffold's own vitest suite, run against the tarballs built above | |
| # rather than the published versions template/package.json pins. This is | |
| # the only CI check that exercises the template's example test, and the | |
| # only one that consumes @databricks/appkit/testing the way a customer | |
| # does — through a real npm install of a packed tarball. Before the zip, | |
| # so a broken example fails the build instead of shipping. | |
| - name: Run the template's own tests | |
| working-directory: pr-template | |
| run: npm test | |
| # npm install above runs under the JFrog .npmrc (setup-jfrog-npm), which | |
| # bakes internal registry URLs into the regenerated locks. Rewrite them back | |
| # to public npm and fail-closed if any non-public registry remains, so the | |
| # shipped scaffold installs from npmjs.org. --allow-file permits the bundled | |
| # appkit/appkit-ui tarballs that prepare-template-artifact.ts pins. | |
| - name: Rewrite and validate template lockfiles registry | |
| run: > | |
| pnpm exec tsx tools/check-template-lock-registry.ts pr-template/pnpm-lock.yaml --rewrite --allow-file && | |
| pnpm exec tsx tools/check-template-lock-registry.ts pr-template/package-lock.json --rewrite --allow-file | |
| - name: Create zip artifact | |
| working-directory: pr-template | |
| run: zip -r "../appkit-template-${{ steps.version.outputs.version }}.zip" . -x 'node_modules/*' | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: appkit-template-${{ steps.version.outputs.version }} | |
| path: appkit-template-${{ steps.version.outputs.version }}.zip | |
| # Build the PR-bot comment: a link to the evals-monitor app, plus a | |
| # self-contained, run-anywhere command that downloads this run's artifact | |
| # and scaffolds an app from it. Every value (run id, repo, artifact name, | |
| # output dir) is baked in so the reader can paste it into any folder — no | |
| # repo checkout or specific cwd required. | |
| - name: Build PR-bot comment | |
| env: | |
| VERSION: ${{ steps.version.outputs.version }} | |
| RUN_ID: ${{ github.run_id }} | |
| REPO: ${{ github.repository }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| run: | | |
| ARTIFACT="appkit-template-${VERSION}" | |
| OUT="appkit-pr-${PR_NUMBER}" | |
| EVALS_URL="https://evals-monitor-6051921418418893.staging.aws.databricksapps.com/prs/appkit/${PR_NUMBER}" | |
| { | |
| echo "<!-- pr-bot -->" | |
| echo "## 🤖 AppKit PR bot" | |
| echo "" | |
| echo "### 🔬 Run evals" | |
| echo "" | |
| echo "Start an eval for this PR from the evals-monitor app: [**Go to Evals Monitor →**](${EVALS_URL})" | |
| echo "" | |
| echo "### 📦 Try this PR's app template" | |
| echo "" | |
| echo "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):" | |
| echo "" | |
| echo '```bash' | |
| echo "gh run download ${RUN_ID} -R ${REPO} -n ${ARTIFACT} -D ${OUT} \\" | |
| echo " && unzip -o \"${OUT}/${ARTIFACT}.zip\" -d \"${OUT}\" \\" | |
| echo " && databricks apps init --template \"${OUT}\"" | |
| echo '```' | |
| echo "" | |
| echo "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." | |
| } > pr-bot-comment.md | |
| # Fork PRs get a read-only GITHUB_TOKEN, so commenting would 403 and fail | |
| # a job the author can't fix. Skip for forks — the command is still in the | |
| # job log above. Matches bundle-size.yml. | |
| - name: Upsert PR-bot comment | |
| if: github.event.pull_request.head.repo.full_name == github.repository | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| env: | |
| COMMENT_PATH: pr-bot-comment.md | |
| with: | |
| script: | | |
| const upsert = require('./.github/scripts/upsert-pr-bot-comment.cjs'); | |
| await upsert({ github, context }); | |
| docs-build: | |
| name: Docs Build | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.docs == 'true' | |
| runs-on: | |
| group: databricks-ghec-untrusted-runner-group | |
| labels: linux-ubuntu-latest-untrusted-2core-8gb | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Setup JFrog npm | |
| uses: ./.github/actions/setup-jfrog-npm | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: .nvmrc | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Docs | |
| run: pnpm run docs:build | |
| - name: Check Generated Docs | |
| run: pnpm run docs:check | |
| - name: Check for uncommitted docs changes | |
| run: | | |
| if ! git diff --exit-code docs/docs/api/; then | |
| echo "❌ Error: Generated docs are out of sync with the codebase." | |
| echo "" | |
| echo "The API documentation in docs/docs/api/ has changes after running docs:generate." | |
| echo "This means the committed docs don't match the current package code." | |
| echo "" | |
| echo "To fix this:" | |
| echo " 1. Run: pnpm docs:build" | |
| echo " 2. Run: pnpm docs:check:fix" | |
| echo " 3. Review and commit the changes" | |
| echo "" | |
| exit 1 | |
| fi | |
| devhub-validation: | |
| name: DevHub Build Validation | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.docs == 'true' | |
| permissions: | |
| contents: read | |
| id-token: write | |
| uses: ./.github/workflows/devhub-build.yml | |
| with: | |
| appkit-remote: ${{ github.event.pull_request.head.repo.clone_url || format('https://github.com/{0}.git', github.repository) }} | |
| appkit-ref: ${{ github.head_ref || github.ref_name }} | |
| # PR refs can't match the public-repos allow-list (main only). | |
| runner-group: databricks-ghec-untrusted-runner-group | |
| runner-label: linux-ubuntu-latest-untrusted-2core-8gb |