Open
Conversation
Jobs are configured as named resources (DATABRICKS_JOB_<KEY> env vars)
and discovered at startup, following the files plugin pattern.
API is scoped to configured jobs:
appkit.jobs('etl').runNow()
appkit.jobs('etl').runNowAndWait()
appkit.jobs('etl').lastRun()
appkit.jobs('etl').listRuns()
appkit.jobs('etl').asUser(req).runNow()
Single-job shorthand via DATABRICKS_JOB_ID env var.
Supports OBO access via asUser(req).
Co-authored-by: Isaac
Signed-off-by: Evgenii Kniazev <evgenii.kniazev@databricks.com>
Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
…nfig Phase 1 of jobs plugin rework: establishes config foundation with TaskType union, three interceptor tiers (read/write/stream), and pure parameter mapping for all 6 task types. Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
…reaming Wave 2 of jobs plugin rework: - Fix connector protobuf types (Waiter access pattern) - Remove waitForRun from connector, add runAndWait async generator in plugin - Wrap reads in execute() with JOBS_READ_DEFAULTS, writes with JOBS_WRITE_DEFAULTS - Add Zod param validation and mapParams integration to runNow - Enrich clientConfig() with JSON Schema per job - Update JobAPI types and adapt existing tests Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
Phase 5 of jobs plugin rework: adds injectRoutes() with 4 endpoints: - POST /:jobKey/run (with ?stream=true SSE support) - GET /:jobKey/runs (paginated) - GET /:jobKey/runs/:runId (detail) - GET /:jobKey/status (latest run) All routes use OBO via asUser(req) and validate job keys. Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
- Fix ERR_HTTP_HEADERS_SENT crash when streaming errors occur after headers are flushed (check res.headersSent before setting status) - Fix spark_jar/sql param mapping to use correct SDK fields (jar_params, sql_params instead of parameters) - Forward abort signal from execute() interceptors to all connector calls for proper timeout/cancellation support - Use Zod result.data after validation to preserve schema transforms and defaults - Validate params even when omitted if a schema is configured - Fix lastRun return type from Run to BaseRun (matches listRuns) - Fix getJobId error message for default job key Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
The asUser() proxy wraps createJobAPI() in user context, but the returned JobAPI closures called this.client after the ALS scope exited, falling back to service principal. Fix by capturing the client and userId eagerly at creation time and passing them explicitly to execute() and connector calls. Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
Migrate streaming to executeStream(), route polling through execute(), use ValidationError, standardize eager captures, tighten types, expose taskType in clientConfig, remove .job() alias, update manifest docs. Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
…ms before streaming - Cap listRuns to [1, 100] in both connector and HTTP route to prevent unbounded memory materialization - Reject negative runId (<=0) in GET/DELETE run handlers - Validate Zod params before entering SSE stream branch so bad params return 400 JSON instead of a generic SSE error event Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
Jobs are configured as named resources (DATABRICKS_JOB_<KEY> env vars)
and discovered at startup, following the files plugin pattern.
API is scoped to configured jobs:
appkit.jobs('etl').runNow()
appkit.jobs('etl').runNowAndWait()
appkit.jobs('etl').lastRun()
appkit.jobs('etl').listRuns()
appkit.jobs('etl').asUser(req).runNow()
Single-job shorthand via DATABRICKS_JOB_ID env var.
Supports OBO access via asUser(req).
Co-authored-by: Isaac
Signed-off-by: Evgenii Kniazev <evgenii.kniazev@databricks.com>
Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
…nfig Phase 1 of jobs plugin rework: establishes config foundation with TaskType union, three interceptor tiers (read/write/stream), and pure parameter mapping for all 6 task types. Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
…reaming Wave 2 of jobs plugin rework: - Fix connector protobuf types (Waiter access pattern) - Remove waitForRun from connector, add runAndWait async generator in plugin - Wrap reads in execute() with JOBS_READ_DEFAULTS, writes with JOBS_WRITE_DEFAULTS - Add Zod param validation and mapParams integration to runNow - Enrich clientConfig() with JSON Schema per job - Update JobAPI types and adapt existing tests Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
Phase 5 of jobs plugin rework: adds injectRoutes() with 4 endpoints: - POST /:jobKey/run (with ?stream=true SSE support) - GET /:jobKey/runs (paginated) - GET /:jobKey/runs/:runId (detail) - GET /:jobKey/status (latest run) All routes use OBO via asUser(req) and validate job keys. Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
- Fix ERR_HTTP_HEADERS_SENT crash when streaming errors occur after headers are flushed (check res.headersSent before setting status) - Fix spark_jar/sql param mapping to use correct SDK fields (jar_params, sql_params instead of parameters) - Forward abort signal from execute() interceptors to all connector calls for proper timeout/cancellation support - Use Zod result.data after validation to preserve schema transforms and defaults - Validate params even when omitted if a schema is configured - Fix lastRun return type from Run to BaseRun (matches listRuns) - Fix getJobId error message for default job key Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
The asUser() proxy wraps createJobAPI() in user context, but the returned JobAPI closures called this.client after the ALS scope exited, falling back to service principal. Fix by capturing the client and userId eagerly at creation time and passing them explicitly to execute() and connector calls. Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
Migrate streaming to executeStream(), route polling through execute(), use ValidationError, standardize eager captures, tighten types, expose taskType in clientConfig, remove .job() alias, update manifest docs. Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
…ms before streaming - Cap listRuns to [1, 100] in both connector and HTTP route to prevent unbounded memory materialization - Reject negative runId (<=0) in GET/DELETE run handlers - Validate Zod params before entering SSE stream branch so bad params return 400 JSON instead of a generic SSE error event Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
…s-plugin-core # Conflicts: # packages/appkit/src/index.ts
execute() returns ExecutionResult<T> (a discriminated union), but the jobs plugin was treating it as plain T. This caused 9 TypeScript errors and 6 test failures. Each call site now checks result.ok before accessing result.data, matching the pattern established by the serving plugin. Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
Merge remote branch and fix execute() call sites: execute() returns ExecutionResult<T> (discriminated union), but the jobs plugin treated results as plain T. Each call site now checks result.ok before accessing result.data, matching the pattern from the serving plugin. Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new resource-scoped “jobs” plugin to @databricks/appkit, following the existing “files” plugin pattern: jobs are discovered from environment variables at startup and exposed via a keyed accessor API, with HTTP routes for triggering and monitoring runs.
Changes:
- Introduces
plugins/jobs(manifest, defaults, params mapping, types, plugin implementation, and extensive tests). - Adds
connectors/jobswith telemetry + cancellation support and updates exports/docs to surface the new plugin and types. - Updates templates and generated API docs/sidebars to include the new Jobs plugin.
Reviewed changes
Copilot reviewed 24 out of 25 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| template/appkit.plugins.json | Adds “jobs” to plugin template metadata + resource description. |
| pnpm-lock.yaml | Locks new dependency (zod@4.3.6) and related lockfile updates. |
| packages/appkit/src/plugins/jobs/types.ts | Public types for Jobs plugin API/config (JobAPI/JobHandle/IJobsConfig). |
| packages/appkit/src/plugins/jobs/plugin.ts | Core JobsPlugin: env discovery, dynamic resource requirements, API methods, HTTP routes. |
| packages/appkit/src/plugins/jobs/params.ts | TaskType-based param mapping into SDK request fields. |
| packages/appkit/src/plugins/jobs/defaults.ts | Execution defaults for read/write/stream operations. |
| packages/appkit/src/plugins/jobs/manifest.json | Plugin manifest + config schema + baseline resource definition. |
| packages/appkit/src/plugins/jobs/index.ts | Barrel exports for Jobs plugin/types. |
| packages/appkit/src/plugins/jobs/tests/plugin.test.ts | Comprehensive unit tests for discovery, API, routes, and validation. |
| packages/appkit/src/plugins/index.ts | Exposes jobs from the plugins barrel. |
| packages/appkit/src/index.ts | Exposes jobs and related public types/configs from package root. |
| packages/appkit/src/connectors/jobs/client.ts | JobsConnector SDK wrapper with telemetry instrumentation + limit handling. |
| packages/appkit/src/connectors/jobs/types.ts | Connector config type (timeout/telemetry). |
| packages/appkit/src/connectors/jobs/index.ts | Connector barrel exports. |
| packages/appkit/src/connectors/index.ts | Exposes jobs connector from connectors barrel. |
| packages/appkit/package.json | Adds zod dependency for runtime param schemas + JSON schema generation. |
| docs/docs/api/appkit/typedoc-sidebar.ts | Adds new Jobs docs entries to sidebar. |
| docs/docs/api/appkit/*.md | Adds generated API docs pages for Jobs plugin types. |
| docs/docs/api/appkit/index.md | Adds Jobs-related types to API index list. |
| docs/docs/api/appkit/Interface.BasePluginConfig.md | Updates “Extended by” list to include IJobsConfig. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
The StreamManager's close handlers cleaned up heartbeats and client tracking but never aborted the stream's AbortController. This left polling loops (e.g. jobs runAndWait) running in the background after SSE connections closed, wasting resources until timeout. Co-authored-by: Isaac Signed-off-by: Atila Fassina <atila@fassina.eu>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Resource-scoped jobs plugin following the files plugin pattern. Jobs are configured as named resources discovered from environment variables at startup.
Design
DATABRICKS_JOB_<KEY>env vars (e.g.DATABRICKS_JOB_ETL=123)DATABRICKS_JOB_IDmaps to the"default"keyCAN_MANAGE_RUNpermissiondatabricks apps init --features jobsAPI
Files changed
plugins/jobs/manifest.json— declares job resource withCAN_MANAGE_RUNpermissionplugins/jobs/types.ts—JobAPI,JobHandle,JobsExport,IJobsConfigtypesplugins/jobs/plugin.ts—JobsPluginwithdiscoverJobs(),getResourceRequirements(), resource-scopedcreateJobAPI()plugins/jobs/index.ts— barrel exportsconnectors/jobs/client.ts—listRunsnow respectslimitparameterplugins/jobs/tests/plugin.test.ts— 32 tests covering discovery, resource requirements, exports, OBO, multi-job, and auto-fillDocumentation safety checklist