Skip to content

feat(bots): onboard reviewer + engineer bots to databricks-bot-engine#464

Open
eric-wang-1990 wants to merge 4 commits into
mainfrom
bot/onboard-bot-engine
Open

feat(bots): onboard reviewer + engineer bots to databricks-bot-engine#464
eric-wang-1990 wants to merge 4 commits into
mainfrom
bot/onboard-bot-engine

Conversation

@eric-wang-1990

Copy link
Copy Markdown
Contributor

Summary

Onboards both databricks-bot-engine bots to databricks-sql-nodejs, PAT-free (App-auth), pinned to engine SHA d05dcb11. Adapted for this repo's TypeScript / npm toolchain. Structured to land in one PR (per the engine's one-PR onboarding checklist).

  • reviewer-bot — reviews every non-fork PR and posts inline findings. This repo has no existing Claude automation, so it's the sole autonomous reviewer — no trigger clash or duplicate coverage.
  • engineer-bot — given a maintainer-labelled issue, reproduces the bug with a failing live tests/e2e test against a warehouse (Thrift backend), fixes the TS, and opens a PR; follows up on review comments.

The engine is pip-installed in REF mode (it can't be uses:-d cross-repo) via two local composites that mirror the databricks-sql-python / databricks-odbc onboardings.

What's in this PR

Path Purpose
.github/actions/install-bot-engine/ REF-mode engine + Claude SDK/CLI install, PAT-free, JFrog-routed
.github/actions/bot-prelude/ mint bot App token + engine-scoped token, Node, engine install. Engine pin lives here (single source of truth)
.github/workflows/reviewer-bot.yml + -followup.yml read-only; Python interpreter only
.github/workflows/engineer-bot.yml + -followup.yml npm ci (JFrog mirror) so the agent can build & test; author requires live e2e, followup runs mocked npm test only
.bot/config.yaml + .bot/prompts/** engineer config + prompts (TS/Node); reviewer additive prompt
tests/e2e/utils/config.ts +token fallback so the e2e token survives the engine's env scrub

TypeScript-specific adaptations

  • Protected runner + JFrog mirror, same as odbc (not GitHub-hosted). setup-jfrog runs before every npm ci; id-token: write on all jobs.
  • npm ci, never npm install. The allowlist and workflows use npm ci only — npm install would rewrite package-lock.json to lockfileVersion 3 and fail the repo's lint gate. No tracked-file churn otherwise (the preparetsc build outputs to gitignored dist/ + lib/version.ts), so no revert step is needed.
  • E2E token via config file. tests/e2e/utils/config.ts reads the PAT from E2E_ACCESS_TOKEN and process.exit(1)s if any of its 7 vars is missing. The engine scrubs *_TOKEN-shaped env vars from the agent subprocess, so the token can't ride an env var — the author workflow writes it to $RUNNER_TEMP/e2e-connection.json and passes the path in DATABRICKS_TEST_CONFIG_FILE (a name the scrub preserves); config.ts falls back to it only when E2E_ACCESS_TOKEN is absent. Env var still wins → normal CI and local dev are byte-for-byte unchanged. (Verified: config.ts typechecks under the repo's pinned TS 5.5.4/strict and is Prettier-clean.)
  • Thrift backend for repros. The engineer job does not build the native kernel binary (needs the private databricks-sql-kernel repo + Rust + napi), so the bug-fix prompt targets the Thrift-backed tests/e2e/*.test.ts suite; kernel-only bugs report blocked.
  • denied_subpaths blocks .github/, native/ (napi kernel binding), and thrift/ (generated stubs).
  • bash_allowlist is npm/mocha (npm test, npm run e2e, npx mocha --config …, npm run build/type-check/lint/prettier, npm ci, git status).

⚠️ Prerequisites — provisioning YOU must do (a PR can't)

The workflows will fail at the first token-mint step until these are in place (this is exactly what happened on the odbc onboarding until the Apps were installed):

  1. Two GitHub Apps, each with contents/pull-requests/issues: write:
    • REVIEW_BOT_APP_ID + REVIEW_BOT_APP_PRIVATE_KEY
    • ENGINEER_BOT_APP_ID + ENGINEER_BOT_APP_PRIVATE_KEY
      (None exist in this repo today — only INTEGRATION_TEST_APP_*.)
  2. Install BOTH Apps on databricks-sql-nodejs AND on databricks-bot-engine (the latter with contents: read) — the engine install mints an engine-scoped token, so the App must see the engine repo. (Missing the repo install → create-github-app-token returns 404 at the prelude.)
  3. Confirm DATABRICKS_HOST / DATABRICKS_TOKEN (already present, used by the e2e job) point at a workspace hosting the databricks-claude-opus-4-8 serving endpoint; TEST_PECO_WAREHOUSE_HTTP_PATH present (used for E2E_PATH).
  4. A maintainer-only engineer-bot label has been created on this repo as part of this change. The reviewer needs no label — it fires on PR open.
  5. issues / workflow_dispatch triggers only register from the default branch, so the engineer workflows go live only after this PR merges.

Verification

  • All 4 workflows + 2 composites + .bot/config.yaml parse; actionlint clean (only the known linux-ubuntu-latest self-hosted-label false positive, same label main.yml uses).
  • tests/e2e/utils/config.ts typechecks under the repo's pinned TypeScript 5.5.4 (strict, ES2018, commonjs, esModuleInterop, node types) and passes Prettier with the repo's .prettierrc.
  • Config has required name/marker_namespace/pr_body_template; fork gates + id-token: write present on all applicable jobs; no reuse of the app-pinned Node.js Integration Tests / Kernel E2E check names.
  • First real end-to-end run happens post-merge (protected runner + warehouse aren't reachable from a review env): after merging + provisioning, open a test PR (reviewer) and label a Bug-typed issue engineer-bot (author).

This pull request and its description were written by Isaac.


This PR was created with GitHub MCP.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

Copy link
Copy Markdown

Thanks for your contribution! To satisfy the DCO policy in our contributing guide every commit message must include a sign-off message. One or more of your commits is missing this message. You can reword previous commit messages with an interactive rebase (git rebase -i main).

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Review bot failed — see workflow logs.

Reason: Phase 2 gh api failed: HTTP 502: We had issues producing the response to your request. Sorry about that. Please try resubmitting your request and contact us if the problem persists. (https://api.githu

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Review bot failed — see workflow logs.

Reason: required env var 'DATABRICKS_TOKEN' is not set; needed by the agent/planner phases

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Review bot failed — see workflow logs.

Reason: model did not call finalize_review and the final text was not parseable JSON: Empty response

Onboards both engine bots to databricks-sql-nodejs, PAT-free (App-auth), pinned
to engine SHA d05dcb11. Single PR, adapted for the TypeScript/npm toolchain.

Reviewer bot (read-only): fires on PR open/update + workflow_dispatch; Python
interpreter + JFrog + engine install; posts inline findings. No existing Claude
automation in this repo, so it's the sole autonomous reviewer — no conflict.

Engineer bot (bug-fix flow, live E2E discipline): on a maintainer `engineer-bot`
label. Installs connector deps (npm ci via JFrog mirror; never npm install, which
would bump package-lock to v3 and fail CI lint), then requires a live tests/e2e
repro against a warehouse over the Thrift backend before fixing. Follow-up runs
the mocked npm test unit suite only (no live creds).

.bot/: engineer config + prompts for TS/Node; reviewer additive prompt.
denied_subpaths blocks .github/, native/ (napi kernel binding), thrift/ (generated
stubs). tests/e2e/utils/config.ts gains a token fallback so E2E_ACCESS_TOKEN
survives the engine's env scrub (the *_TOKEN vars are stripped from the agent
subprocess; without it config.ts process.exit(1)s the whole suite); env var still
wins, so normal CI/local dev is unchanged.

Two local composites (bot-prelude, install-bot-engine) mirror the sql-python /
odbc onboarding — the engine can't be `uses:`-d cross-repo, so it's pip-installed
in REF mode. Runs on the protected runner group + JFrog mirror like the other
internal drivers.

Co-authored-by: Isaac

Signed-off-by: eric-wang-1990 <e.wang@databricks.com>

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verdict: 3 High

Onboarding scaffolding looks solid overall; the config.ts token fallback is correctly gated so normal CI/local dev is unchanged. One high concern repeated across three files: DATABRICKS_HOST/DATABRICKS_TOKEN are azure-prod-environment secrets (per engineer-bot.yml's own comment and main.yml/kernel-e2e.yml), but the reviewer, reviewer-followup, and engineer-followup jobs reference them without declaring environment: azure-prod, so they'll resolve empty and break the model call.

PR_NUMBER: ${{ steps.inputs.outputs.pr_number }}
HEAD_SHA: ${{ steps.inputs.outputs.head_sha }}
DRY_RUN: ${{ steps.inputs.outputs.dry_run }}
MODEL_ENDPOINT: https://${{ secrets.DATABRICKS_HOST }}/serving-endpoints/databricks-claude-opus-4-8/invocations

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 High — This job references secrets.DATABRICKS_HOST and secrets.DATABRICKS_TOKEN to build MODEL_ENDPOINT and authenticate the model, but the review job declares no environment:. In this repo those secrets are scoped to the azure-prod GitHub environment — every other consumer (main.yml:110, kernel-e2e.yml:179, and the engineer author job at engineer-bot.yml:50, whose own comment says "DATABRICKS_HOST / DATABRICKS_TOKEN ... live here") declares environment: azure-prod to reach them. Without it, environment-scoped secrets resolve to the empty string, yielding MODEL_ENDPOINT=https:///serving-endpoints/... and an empty token — the reviewer run fails at the model call. Add environment: azure-prod to this job (as the engineer author job does).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Nope those 2 are also in the default environment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I hear you that these may also be available in the default environment — but I can't verify secret scoping from the source, and the code still declares no environment: here while three sibling jobs (main.yml:110, kernel-e2e.yml:179, engineer-bot.yml:50) all set environment: azure-prod specifically to reach these same two secrets. If they truly resolved in the default environment, those jobs wouldn't need the declaration. Since this hinges on the actual GitHub environment config, which isn't visible in the repo, I'll leave this open for a human to confirm the secret scoping before dismissing it. If the secrets do resolve in the default environment, this is a safe no-op; if not, the reviewer run fails at the model call with an empty host/token.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

NEEDS HUMAN DECISION — the bots can't resolve this thread; a maintainer's input is required.

The comment targets .github/workflows/reviewer-bot.yml, which is a denied path in this job (no edits under .github/ are possible here). Beyond that, resolving it hinges on a repo-settings fact I can't verify from the tree: the bot claims DATABRICKS_HOST/DATABRICKS_TOKEN are scoped only to the azure-prod environment, while the PR author (eric-wang-1990) states they are also present in the default environment — in which case no environment: azure-prod is needed. Confirming which is correct requires inspecting the repo's GitHub environment/secret configuration, an admin/out-of-band check only a human can perform. Flagging for a human to confirm secret scoping and, if needed, add environment: azure-prod in a separate change.

TRIGGER_COMMENT_ID: ${{ github.event.comment.id }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
MODEL_ENDPOINT: https://${{ secrets.DATABRICKS_HOST }}/serving-endpoints/databricks-claude-opus-4-8/invocations

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 High — Same issue as the reviewer author workflow: the followup job uses secrets.DATABRICKS_HOST / secrets.DATABRICKS_TOKEN for MODEL_ENDPOINT/auth but declares no environment:. Since those secrets live in the azure-prod environment in this repo, they resolve empty here and the model call fails. Add environment: azure-prod to the job.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Nope those 2 are also in the default environment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I can't verify secret scoping from the source alone — it's repo/environment config that isn't visible in the workflow file. My concern was specifically that these two secrets resolve empty without environment: azure-prod. If they're genuinely also defined in the default environment, this is a non-issue; but since a wrong assumption here means the model call silently fails at runtime, I'd rather leave this open for a human to confirm the default-environment secret setup before dismissing it. If they're present there, please close this out.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

NEEDS HUMAN DECISION — the bots can't resolve this thread; a maintainer's input is required.

Cannot action here: the comment targets .github/workflows/reviewer-bot-followup.yml, and .github/ is a denied/non-writable path in this PR, so no edit is possible. Separately, the correctness of the finding depends on whether DATABRICKS_HOST/DATABRICKS_TOKEN are populated in the repo's default environment (as the PR author asserts) or only in the azure-prod environment (as the bot claims) — that's a repo secrets/environment configuration fact that can't be verified from the code and needs a human with repo-admin access. A human should confirm the secrets resolve in the default environment; if they do, the bot's finding is a false positive and no environment: azure-prod is needed. Thread has converged on the author's disagreement.

PR_TITLE: ${{ github.event.pull_request.title }}
PR_URL: ${{ github.event.pull_request.html_url }}
TRIGGER_COMMENT_ID: ${{ github.event.comment.id }}
MODEL_ENDPOINT: https://${{ secrets.DATABRICKS_HOST }}/serving-endpoints/databricks-claude-opus-4-8/invocations

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 High — The engineer author workflow declares environment: azure-prod (engineer-bot.yml:50) precisely because DATABRICKS_HOST/DATABRICKS_TOKEN are environment-scoped there, but this follow-up job references the same two secrets for MODEL_ENDPOINT/DATABRICKS_TOKEN with no environment: declared. They will resolve to empty strings and the follow-up model invocation will fail. Add environment: azure-prod to the followup job.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Nope those 2 are also in the default environment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The file still declares no environment:, and I can't view secret scoping from the source. If DATABRICKS_HOST/DATABRICKS_TOKEN are truly repository-level (default) secrets, this resolves fine and my concern is void — please confirm against the repo/org secret settings, since engineer-bot.yml opting into environment: azure-prod implies environment scoping for at least one of them. Keeping this open for a human to verify the scoping before merge.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

NEEDS HUMAN DECISION — the bots can't resolve this thread; a maintainer's input is required.

No code change is possible or warranted here. The comment targets .github/workflows/engineer-bot-followup.yml, which is a denied (non-writable) path for this job, so the requested environment: azure-prod edit cannot be applied. More fundamentally, the review-bot's premise — that DATABRICKS_HOST/DATABRICKS_TOKEN resolve to empty without an environment: declaration — depends on GitHub default-vs-environment-scoped secret configuration that cannot be read or verified from this runner. The PR author (@eric-wang-1990) has already authoritatively refuted the concern ("those 2 are also in the default environment"), so the thread has converged. Flagging for a human maintainer with repo settings access to confirm the default-environment secrets; nothing to change in this PR.

@eric-wang-1990 eric-wang-1990 added the engineer-bot Maintainer-only: triggers the autonomous engineer-bot (bug-fix author on issues; follow-up on PRs) label Jul 27, 2026
Applies the reviewer-bot hardening finding (raised on the odbc onboarding PR) to
this repo:

- Reviewer + reviewer-followup: drop the redundant `setup-jfrog` step. The engine
  install (install-bot-engine, use-jfrog=true) already mints + scopes its own JFrog
  creds in job-local 0600 files wiped in an EXIT trap, and the reviewer runs no npm
  install of its own. The shared setup-jfrog exported JFROG_ACCESS_TOKEN to
  $GITHUB_ENV and wrote a tokened ~/.npmrc, both persisting into the model-driven
  Run reviewer step.

- Engineer author + followup: keep setup-jfrog (npm ci needs it) but add a "Scrub
  JFrog credentials" step after npm ci and before the agent — rm ~/.npmrc + blank
  JFROG_ACCESS_TOKEN. The agent's test commands (npm test / npm run e2e) don't need
  the registry, so this is safe.

The shared .github/actions/setup-jfrog composite is untouched (real CI depends on
it).

Signed-off-by: eric-wang-1990 <e.wang@databricks.com>

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verdict: 1 Low

Looks good — a clean, well-documented bot-onboarding PR that is almost entirely CI/prompt scaffolding; the only executable change (tokenFromConfigFile fallback in config.ts) preserves normal CI/local behavior (env var still wins). One low note: the new helper's catch collapses "missing file" and "malformed file" into the same silent undefined, which can produce a misleading "token is missing" abort.

Comment thread tests/e2e/utils/config.ts
Addresses:
  - #3655446201 at tests/e2e/utils/config.ts:78

Signed-off-by: peco-engineer-bot[bot] <peco-engineer-bot[bot]@users.noreply.github.com>

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verdict: 1 Low

Looks good — this is a well-documented bots-onboarding PR that is almost entirely CI/YAML and prompt prose; the sole executable change (tests/e2e/utils/config.ts token fallback) is correct and leaves normal CI/local dev unchanged. One low-severity note about logging the raw parse exception in the credential-config path.

Comment thread tests/e2e/utils/config.ts Outdated
Addresses:
  - #3655491620 at tests/e2e/utils/config.ts:80

Signed-off-by: peco-engineer-bot[bot] <peco-engineer-bot[bot]@users.noreply.github.com>

@peco-review-bot peco-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verdict: 3 High

Mostly solid onboarding PR; the config.ts token fallback is careful (env var wins, credential-safe error logging) and the workflow security gates are well-reasoned. One repeated concern worth confirming: three of the four new bot workflows use secrets.DATABRICKS_HOST/DATABRICKS_TOKEN but omit environment: azure-prod, which the engineer-bot author job and main.yml's e2e job both declare to reach those same (apparently environment-scoped) secrets — if so, those three jobs will get empty values and fail.

Comment thread .github/workflows/reviewer-bot.yml
Comment thread .github/workflows/reviewer-bot-followup.yml
Comment thread .github/workflows/engineer-bot-followup.yml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-assisted engineer-bot Maintainer-only: triggers the autonomous engineer-bot (bug-fix author on issues; follow-up on PRs)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants