Skip to content

Expose the workspace context to bundle templates as .workspace - #7349

Merged
pavloKozlov merged 5 commits into
mainfrom
workspace-context-template-data
Nov 6, 2026
Merged

pavloKozlov merged 5 commits into
mainfrom
workspace-context-template-data

Conversation

@pavloKozlov

@pavloKozlov pavloKozlov commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Changes

Bundle templates can read the workspace of the selected profile as .workspace, in template files and in the schema (defaults, descriptions, messages). It has Hostname, ID and URL. URL "/jobs" returns a workspace URL and adds ?w=<id> when the profile, an environment variable, or a bundle in the working directory sets the workspace ID. ID fails when the ID is unknown and doesn't make a request to find it. A schema input named workspace takes precedence.

Schema rendering now renders the default of a property that already has an input value, instead of returning template text. The input value is kept.

Why

When several workspaces share one host, workspace_host can't select the workspace. An ID that the SDK resolved from host metadata is not added to URLs, because a profile without workspace_id would then not match the host under strict profile matching.

Tests

Acceptance tests cover URLs and IDs for each kind of profile, env vars, a bundle in the working directory, invalid paths, the workspace input rules, and a schema rerender with edited inputs. Unit tests cover prompts and adb-<id> hosts.

This pull request and its description were written by Isaac.

@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Commit: ea56a0432 | Workflow run

Regression test report

Selected 2 changed tests (limit=20, 0 not selected)

4 tests: regression=4 unreleased=0 coverage=0 failing=0
test branch main (eb1328d) latest (v1.24.0)
TestAccept/bundle/templates-machinery/workspace_variable/input/DMS= ✅ ❌ ❌
TestAccept/bundle/templates-machinery/workspace_variable/input/DMS=true ✅ ❌ ❌
TestAccept/bundle/templates-machinery/workspace_variable/runtime/DMS= ✅ ❌ ❌
TestAccept/bundle/templates-machinery/workspace_variable/runtime/DMS=true ✅ ❌ ❌
TestAccept/bundle/templates-machinery/workspace_variable/input/DMS=: branch ✅ | main (eb1328d) ❌ | latest (v1.24.0) ❌

main (eb1328d):

acceptance_test.go:1345: Diff:
        --- bundle/templates-machinery/workspace_variable/input/output.txt
        +++ /tmp/TestAcceptbundletemplates-machineryworkspace_variableinputD2284787791/002/output.txt
        @@ -97,12 +97,12 @@
         
         >>> [CLI] bundle debug render-template-schema ./undeclared --input-file input.value.json
         {
        -  "welcome_message": "workspace: {[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}",
        +  "welcome_message": "workspace: team-dev",
           "success_message": null,
           "properties": {}
         }
         
         >>> [CLI] bundle init ./undeclared --config-file input.value.json
        -workspace: {[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}
        -✨ Successfully initialized template
        -workspace: {[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}
        +Error: variable "workspace" not defined
        +
        +Exit code: 1

latest (v1.24.0):

acceptance_test.go:1345: Diff:
        --- bundle/templates-machinery/workspace_variable/input/output.txt
        +++ /tmp/TestAcceptbundletemplates-machineryworkspace_variableinputD404130768/002/output.txt
        @@ -97,12 +97,12 @@
         
         >>> [CLI] bundle debug render-template-schema ./undeclared --input-file input.value.json
         {
        -  "welcome_message": "workspace: {[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}",
        +  "welcome_message": "workspace: team-dev",
           "success_message": null,
           "properties": {}
         }
         
         >>> [CLI] bundle init ./undeclared --config-file input.value.json
        -workspace: {[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}
        -✨ Successfully initialized template
        -workspace: {[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}
        +Error: variable "workspace" not defined
        +
        +Exit code: 1
        
FAIL
TestAccept/bundle/templates-machinery/workspace_variable/input/DMS=true: branch ✅ | main (eb1328d) ❌ | latest (v1.24.0) ❌

main (eb1328d):

acceptance_test.go:1345: Diff:
        --- bundle/templates-machinery/workspace_variable/input/output.txt
        +++ /tmp/TestAcceptbundletemplates-machineryworkspace_variableinputD2722912787/002/output.txt
        @@ -97,12 +97,12 @@
         
         >>> [CLI] bundle debug render-template-schema ./undeclared --input-file input.value.json
         {
        -  "welcome_message": "workspace: {[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}",
        +  "welcome_message": "workspace: team-dev",
           "success_message": null,
           "properties": {}
         }
         
         >>> [CLI] bundle init ./undeclared --config-file input.value.json
        -workspace: {[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}
        -✨ Successfully initialized template
        -workspace: {[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}
        +Error: variable "workspace" not defined
        +
        +Exit code: 1

latest (v1.24.0): same output as main (eb1328d)

TestAccept/bundle/templates-machinery/workspace_variable/runtime/DMS=: branch ✅ | main (eb1328d) ❌ | latest (v1.24.0) ❌

main (eb1328d):

acceptance_test.go:1345: Diff:
        --- bundle/templates-machinery/workspace_variable/runtime/output.txt
        +++ /tmp/TestAcceptbundletemplates-machineryworkspace_variableruntime4144763082/002/output.txt
        @@ -2,196 +2,6 @@
         === Profile workspace_classic
         
         >>> [CLI] bundle debug render-template-schema ./urls --profile workspace_classic
        -{
        -  "welcome_message": "Initializing for [DATABRICKS_URL]",
        -  "success_message": "Open [DATABRICKS_URL]/jobs?view=list#top",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[DATABRICKS_URL]/jobs"
        -    },
        -    "path": {
        -      "description": "Path to open on [DATABRICKS_HOST]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        +Error: property path: failed to render template "Path to open on {{ .workspace.Hostname }}": template: base:1:29: executing "base" at <.workspace.Hostname>: nil pointer evaluating interface {}.Hostname
         
        ->>> [CLI] bundle init ./urls --profile workspace_classic
        -Initializing for [DATABRICKS_URL]
        -Open [DATABRICKS_URL]/jobs?view=list#top
        -workspace_host: [DATABRICKS_URL]
        -Hostname: [DATABRICKS_HOST]
        -URL: [DATABRICKS_URL]
        -URL "/jobs": [DATABRICKS_URL]/jobs
        -URL "/jobs?view=list#top": [DATABRICKS_URL]/jobs?view=list#top
        -jobs_url: [DATABRICKS_URL]/jobs
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:[DATABRICKS_URL]/jobs path:/jobs?view=list#top workspace:{[DATABRICKS_HOST] [DATABRICKS_URL] [WORKSPACE_ID] }]
        -
        -=== Profile workspace_classic_id
        -
        ->>> [CLI] bundle debug render-template-schema ./urls --profile workspace_classic_id
        -{
        -  "welcome_message": "Initializing for [DATABRICKS_URL]?w=[WORKSPACE_ID]",
        -  "success_message": "Open [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[DATABRICKS_URL]/jobs?w=[WORKSPACE_ID]"
        -    },
        -    "path": {
        -      "description": "Path to open on [DATABRICKS_HOST]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        -
        ->>> [CLI] bundle init ./urls --profile workspace_classic_id
        -Initializing for [DATABRICKS_URL]?w=[WORKSPACE_ID]
        -Open [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top
        -workspace_host: [DATABRICKS_URL]
        -Hostname: [DATABRICKS_HOST]
        -URL: [DATABRICKS_URL]?w=[WORKSPACE_ID]
        -URL "/jobs": [DATABRICKS_URL]/jobs?w=[WORKSPACE_ID]
        -URL "/jobs?view=list#top": [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top
        -jobs_url: [DATABRICKS_URL]/jobs?w=[WORKSPACE_ID]
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:[DATABRICKS_URL]/jobs?w=[WORKSPACE_ID] path:/jobs?view=list#top workspace:{[DATABRICKS_HOST] [DATABRICKS_URL] [WORKSPACE_ID] [WORKSPACE_ID]}]
        -
        -=== Profile workspace_custom_host
        -
        ->>> [CLI] bundle debug render-template-schema ./urls --profile workspace_custom_host
        -{
        -  "welcome_message": "Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]",
        -  "success_message": "Open [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]"
        -    },
        -    "path": {
        -      "description": "Path to open on [CUSTOM_HOSTNAME]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        -
        ->>> [CLI] bundle init ./urls --profile workspace_custom_host
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Open [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top
        -workspace_host: [CUSTOM_HOST]
        -Hostname: [CUSTOM_HOSTNAME]
        -URL: [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -URL "/jobs": [CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]
        -URL "/jobs?view=list#top": [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top
        -jobs_url: [CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:[CUSTOM_HOST]/jobs?w=[WORKSPACE_ID] path:/jobs?view=list#top workspace:{[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}]
        -
        -=== Profile no_workspace_id
        -
        ->>> [CLI] bundle debug render-template-schema ./urls --profile no_workspace_id
        -{
        -  "welcome_message": "Initializing for [DATABRICKS_URL]",
        -  "success_message": "Open [DATABRICKS_URL]/jobs?view=list#top",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[DATABRICKS_URL]/jobs"
        -    },
        -    "path": {
        -      "description": "Path to open on [DATABRICKS_HOST]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        -
        ->>> [CLI] bundle init ./urls --profile no_workspace_id
        -Initializing for [DATABRICKS_URL]
        -Open [DATABRICKS_URL]/jobs?view=list#top
        -workspace_host: [DATABRICKS_URL]
        -Hostname: [DATABRICKS_HOST]
        -URL: [DATABRICKS_URL]
        -URL "/jobs": [DATABRICKS_URL]/jobs
        -URL "/jobs?view=list#top": [DATABRICKS_URL]/jobs?view=list#top
        -jobs_url: [DATABRICKS_URL]/jobs
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:[DATABRICKS_URL]/jobs path:/jobs?view=list#top workspace:{[DATABRICKS_HOST] [DATABRICKS_URL]  }]
        -
        -=== Rerender and init with edited inputs
        -
        ->>> [CLI] bundle debug render-template-schema ./urls --profile workspace_custom_host --input-file input.edited.json
        -{
        -  "welcome_message": "Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]",
        -  "success_message": "Open [CUSTOM_HOST]/pipelines?tab=all&w=[WORKSPACE_ID]",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]"
        -    },
        -    "path": {
        -      "description": "Path to open on [CUSTOM_HOSTNAME]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        -
        ->>> [CLI] bundle init ./urls --profile workspace_custom_host --config-file input.edited.json
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Open [CUSTOM_HOST]/pipelines?tab=all&w=[WORKSPACE_ID]
        -workspace_host: [CUSTOM_HOST]
        -Hostname: [CUSTOM_HOSTNAME]
        -URL: [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -URL "/jobs": [CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]
        -URL "/pipelines?tab=all": [CUSTOM_HOST]/pipelines?tab=all&w=[WORKSPACE_ID]
        -jobs_url: https://example.test/my-jobs
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:https://example.test/my-jobs path:/pipelines?tab=all workspace:{[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}]
        -
        -=== Invalid URL paths
        -
        ->>> musterr [CLI] bundle init ./urls --profile workspace_custom_host --config-file input.absolute-url.json
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Error: failed to compute file content for urls.txt.tmpl. template: :6:25: executing "" at <$ws.URL>: error calling URL: workspace URL path "https://other.test/jobs" must be relative to the workspace host
        -
        ->>> musterr [CLI] bundle init ./urls --profile workspace_custom_host --config-file input.workspace-selector.json
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Error: failed to compute file content for urls.txt.tmpl. template: :6:25: executing "" at <$ws.URL>: error calling URL: workspace URL path "/jobs?o=123" must not set the "o" query parameter, the workspace is selected by the profile
        -
        ->>> musterr [CLI] bundle init ./urls --profile workspace_custom_host --config-file input.semicolon.json
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Error: failed to compute file content for urls.txt.tmpl. template: :6:25: executing "" at <$ws.URL>: error calling URL: failed to parse query of workspace URL path "/jobs?w=999;x=1": invalid semicolon separator in query
        -
        -=== Workspace ID from environment variables
        -
        ->>> DATABRICKS_CONFIG_FILE=/dev/null DATABRICKS_HOST=[CUSTOM_HOST] DATABRICKS_WORKSPACE_ID=[WORKSPACE_ID] [CLI] bundle init ./urls
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Open [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top
        -URL: [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -URL "/jobs": [CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]
        -URL "/jobs?view=list#top": [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top
        -
        -=== Workspace ID from the bundle in the working directory
        -
        ->>> [CLI] bundle init ../urls
        -Initializing for [DATABRICKS_URL]?w=[WORKSPACE_ID]
        -Open [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top
        -URL: [DATABRICKS_URL]?w=[WORKSPACE_ID]
        -URL "/jobs": [DATABRICKS_URL]/jobs?w=[WORKSPACE_ID]
        -URL "/jobs?view=list#top": [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top
        -
        -=== ID
        -
        ->>> [CLI] bundle init ./id --profile workspace_classic
        -✨ Successfully initialized template
        -ID: [WORKSPACE_ID]
        -
        ->>> [CLI] bundle init ./id --profile workspace_custom_host
        -✨ Successfully initialized template
        -ID: [WORKSPACE_ID]
        -
        ->>> musterr [CLI] bundle init ./id --profile no_workspace_id
        -Error: failed to compute file content for id.txt.tmpl. template: :1:17: executing "" at <.workspace.ID>: error calling ID: cannot determine workspace ID, please set workspace_id in the configuration profile or the DATABRICKS_WORKSPACE_ID environment variable
        -
... (2 more lines truncated, raise DATABRICKS_CLI_TEST_MAX_LOG to see more)

latest (v1.24.0): same output as main (eb1328d)

TestAccept/bundle/templates-machinery/workspace_variable/runtime/DMS=true: branch ✅ | main (eb1328d) ❌ | latest (v1.24.0) ❌

main (eb1328d):

acceptance_test.go:1345: Diff:
        --- bundle/templates-machinery/workspace_variable/runtime/output.txt
        +++ /tmp/TestAcceptbundletemplates-machineryworkspace_variableruntime2054667531/002/output.txt
        @@ -2,196 +2,6 @@
         === Profile workspace_classic
         
         >>> [CLI] bundle debug render-template-schema ./urls --profile workspace_classic
        -{
        -  "welcome_message": "Initializing for [DATABRICKS_URL]",
        -  "success_message": "Open [DATABRICKS_URL]/jobs?view=list#top",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[DATABRICKS_URL]/jobs"
        -    },
        -    "path": {
        -      "description": "Path to open on [DATABRICKS_HOST]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        +Error: property path: failed to render template "Path to open on {{ .workspace.Hostname }}": template: base:1:29: executing "base" at <.workspace.Hostname>: nil pointer evaluating interface {}.Hostname
         
        ->>> [CLI] bundle init ./urls --profile workspace_classic
        -Initializing for [DATABRICKS_URL]
        -Open [DATABRICKS_URL]/jobs?view=list#top
        -workspace_host: [DATABRICKS_URL]
        -Hostname: [DATABRICKS_HOST]
        -URL: [DATABRICKS_URL]
        -URL "/jobs": [DATABRICKS_URL]/jobs
        -URL "/jobs?view=list#top": [DATABRICKS_URL]/jobs?view=list#top
        -jobs_url: [DATABRICKS_URL]/jobs
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:[DATABRICKS_URL]/jobs path:/jobs?view=list#top workspace:{[DATABRICKS_HOST] [DATABRICKS_URL] [WORKSPACE_ID] }]
        -
        -=== Profile workspace_classic_id
        -
        ->>> [CLI] bundle debug render-template-schema ./urls --profile workspace_classic_id
        -{
        -  "welcome_message": "Initializing for [DATABRICKS_URL]?w=[WORKSPACE_ID]",
        -  "success_message": "Open [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[DATABRICKS_URL]/jobs?w=[WORKSPACE_ID]"
        -    },
        -    "path": {
        -      "description": "Path to open on [DATABRICKS_HOST]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        -
        ->>> [CLI] bundle init ./urls --profile workspace_classic_id
        -Initializing for [DATABRICKS_URL]?w=[WORKSPACE_ID]
        -Open [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top
        -workspace_host: [DATABRICKS_URL]
        -Hostname: [DATABRICKS_HOST]
        -URL: [DATABRICKS_URL]?w=[WORKSPACE_ID]
        -URL "/jobs": [DATABRICKS_URL]/jobs?w=[WORKSPACE_ID]
        -URL "/jobs?view=list#top": [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top
        -jobs_url: [DATABRICKS_URL]/jobs?w=[WORKSPACE_ID]
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:[DATABRICKS_URL]/jobs?w=[WORKSPACE_ID] path:/jobs?view=list#top workspace:{[DATABRICKS_HOST] [DATABRICKS_URL] [WORKSPACE_ID] [WORKSPACE_ID]}]
        -
        -=== Profile workspace_custom_host
        -
        ->>> [CLI] bundle debug render-template-schema ./urls --profile workspace_custom_host
        -{
        -  "welcome_message": "Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]",
        -  "success_message": "Open [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]"
        -    },
        -    "path": {
        -      "description": "Path to open on [CUSTOM_HOSTNAME]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        -
        ->>> [CLI] bundle init ./urls --profile workspace_custom_host
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Open [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top
        -workspace_host: [CUSTOM_HOST]
        -Hostname: [CUSTOM_HOSTNAME]
        -URL: [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -URL "/jobs": [CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]
        -URL "/jobs?view=list#top": [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top
        -jobs_url: [CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:[CUSTOM_HOST]/jobs?w=[WORKSPACE_ID] path:/jobs?view=list#top workspace:{[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}]
        -
        -=== Profile no_workspace_id
        -
        ->>> [CLI] bundle debug render-template-schema ./urls --profile no_workspace_id
        -{
        -  "welcome_message": "Initializing for [DATABRICKS_URL]",
        -  "success_message": "Open [DATABRICKS_URL]/jobs?view=list#top",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[DATABRICKS_URL]/jobs"
        -    },
        -    "path": {
        -      "description": "Path to open on [DATABRICKS_HOST]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        -
        ->>> [CLI] bundle init ./urls --profile no_workspace_id
        -Initializing for [DATABRICKS_URL]
        -Open [DATABRICKS_URL]/jobs?view=list#top
        -workspace_host: [DATABRICKS_URL]
        -Hostname: [DATABRICKS_HOST]
        -URL: [DATABRICKS_URL]
        -URL "/jobs": [DATABRICKS_URL]/jobs
        -URL "/jobs?view=list#top": [DATABRICKS_URL]/jobs?view=list#top
        -jobs_url: [DATABRICKS_URL]/jobs
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:[DATABRICKS_URL]/jobs path:/jobs?view=list#top workspace:{[DATABRICKS_HOST] [DATABRICKS_URL]  }]
        -
        -=== Rerender and init with edited inputs
        -
        ->>> [CLI] bundle debug render-template-schema ./urls --profile workspace_custom_host --input-file input.edited.json
        -{
        -  "welcome_message": "Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]",
        -  "success_message": "Open [CUSTOM_HOST]/pipelines?tab=all&w=[WORKSPACE_ID]",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]"
        -    },
        -    "path": {
        -      "description": "Path to open on [CUSTOM_HOSTNAME]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        -
        ->>> [CLI] bundle init ./urls --profile workspace_custom_host --config-file input.edited.json
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Open [CUSTOM_HOST]/pipelines?tab=all&w=[WORKSPACE_ID]
        -workspace_host: [CUSTOM_HOST]
        -Hostname: [CUSTOM_HOSTNAME]
        -URL: [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -URL "/jobs": [CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]
        -URL "/pipelines?tab=all": [CUSTOM_HOST]/pipelines?tab=all&w=[WORKSPACE_ID]
        -jobs_url: https://example.test/my-jobs
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:https://example.test/my-jobs path:/pipelines?tab=all workspace:{[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}]
        -
        -=== Invalid URL paths
        -
        ->>> musterr [CLI] bundle init ./urls --profile workspace_custom_host --config-file input.absolute-url.json
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Error: failed to compute file content for urls.txt.tmpl. template: :6:25: executing "" at <$ws.URL>: error calling URL: workspace URL path "https://other.test/jobs" must be relative to the workspace host
        -
        ->>> musterr [CLI] bundle init ./urls --profile workspace_custom_host --config-file input.workspace-selector.json
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Error: failed to compute file content for urls.txt.tmpl. template: :6:25: executing "" at <$ws.URL>: error calling URL: workspace URL path "/jobs?o=123" must not set the "o" query parameter, the workspace is selected by the profile
        -
        ->>> musterr [CLI] bundle init ./urls --profile workspace_custom_host --config-file input.semicolon.json
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Error: failed to compute file content for urls.txt.tmpl. template: :6:25: executing "" at <$ws.URL>: error calling URL: failed to parse query of workspace URL path "/jobs?w=999;x=1": invalid semicolon separator in query
        -
        -=== Workspace ID from environment variables
        -
        ->>> DATABRICKS_CONFIG_FILE=/dev/null DATABRICKS_HOST=[CUSTOM_HOST] DATABRICKS_WORKSPACE_ID=[WORKSPACE_ID] [CLI] bundle init ./urls
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Open [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top
        -URL: [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -URL "/jobs": [CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]
        -URL "/jobs?view=list#top": [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top
        -
        -=== Workspace ID from the bundle in the working directory
        -
        ->>> [CLI] bundle init ../urls
        -Initializing for [DATABRICKS_URL]?w=[WORKSPACE_ID]
        -Open [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top
        -URL: [DATABRICKS_URL]?w=[WORKSPACE_ID]
        -URL "/jobs": [DATABRICKS_URL]/jobs?w=[WORKSPACE_ID]
        -URL "/jobs?view=list#top": [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top
        -
        -=== ID
        -
        ->>> [CLI] bundle init ./id --profile workspace_classic
        -✨ Successfully initialized template
        -ID: [WORKSPACE_ID]
        -
        ->>> [CLI] bundle init ./id --profile workspace_custom_host
        -✨ Successfully initialized template
        -ID: [WORKSPACE_ID]
        -
        ->>> musterr [CLI] bundle init ./id --profile no_workspace_id
        -Error: failed to compute file content for id.txt.tmpl. template: :1:17: executing "" at <.workspace.ID>: error calling ID: cannot determine workspace ID, please set workspace_id in the configuration profile or the DATABRICKS_WORKSPACE_ID environment variable
        -
... (4 more lines truncated, raise DATABRICKS_CLI_TEST_MAX_LOG to see more)

latest (v1.24.0):

acceptance_test.go:1345: Diff:
        --- bundle/templates-machinery/workspace_variable/runtime/output.txt
        +++ /tmp/TestAcceptbundletemplates-machineryworkspace_variableruntime88469069/002/output.txt
        @@ -2,196 +2,6 @@
         === Profile workspace_classic
         
         >>> [CLI] bundle debug render-template-schema ./urls --profile workspace_classic
        -{
        -  "welcome_message": "Initializing for [DATABRICKS_URL]",
        -  "success_message": "Open [DATABRICKS_URL]/jobs?view=list#top",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[DATABRICKS_URL]/jobs"
        -    },
        -    "path": {
        -      "description": "Path to open on [DATABRICKS_HOST]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        +Error: property path: failed to render template "Path to open on {{ .workspace.Hostname }}": template: base:1:29: executing "base" at <.workspace.Hostname>: nil pointer evaluating interface {}.Hostname
         
        ->>> [CLI] bundle init ./urls --profile workspace_classic
        -Initializing for [DATABRICKS_URL]
        -Open [DATABRICKS_URL]/jobs?view=list#top
        -workspace_host: [DATABRICKS_URL]
        -Hostname: [DATABRICKS_HOST]
        -URL: [DATABRICKS_URL]
        -URL "/jobs": [DATABRICKS_URL]/jobs
        -URL "/jobs?view=list#top": [DATABRICKS_URL]/jobs?view=list#top
        -jobs_url: [DATABRICKS_URL]/jobs
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:[DATABRICKS_URL]/jobs path:/jobs?view=list#top workspace:{[DATABRICKS_HOST] [DATABRICKS_URL] [WORKSPACE_ID] }]
        -
        -=== Profile workspace_classic_id
        -
        ->>> [CLI] bundle debug render-template-schema ./urls --profile workspace_classic_id
        -{
        -  "welcome_message": "Initializing for [DATABRICKS_URL]?w=[WORKSPACE_ID]",
        -  "success_message": "Open [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[DATABRICKS_URL]/jobs?w=[WORKSPACE_ID]"
        -    },
        -    "path": {
        -      "description": "Path to open on [DATABRICKS_HOST]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        -
        ->>> [CLI] bundle init ./urls --profile workspace_classic_id
        -Initializing for [DATABRICKS_URL]?w=[WORKSPACE_ID]
        -Open [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top
        -workspace_host: [DATABRICKS_URL]
        -Hostname: [DATABRICKS_HOST]
        -URL: [DATABRICKS_URL]?w=[WORKSPACE_ID]
        -URL "/jobs": [DATABRICKS_URL]/jobs?w=[WORKSPACE_ID]
        -URL "/jobs?view=list#top": [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top
        -jobs_url: [DATABRICKS_URL]/jobs?w=[WORKSPACE_ID]
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:[DATABRICKS_URL]/jobs?w=[WORKSPACE_ID] path:/jobs?view=list#top workspace:{[DATABRICKS_HOST] [DATABRICKS_URL] [WORKSPACE_ID] [WORKSPACE_ID]}]
        -
        -=== Profile workspace_custom_host
        -
        ->>> [CLI] bundle debug render-template-schema ./urls --profile workspace_custom_host
        -{
        -  "welcome_message": "Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]",
        -  "success_message": "Open [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]"
        -    },
        -    "path": {
        -      "description": "Path to open on [CUSTOM_HOSTNAME]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        -
        ->>> [CLI] bundle init ./urls --profile workspace_custom_host
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Open [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top
        -workspace_host: [CUSTOM_HOST]
        -Hostname: [CUSTOM_HOSTNAME]
        -URL: [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -URL "/jobs": [CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]
        -URL "/jobs?view=list#top": [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top
        -jobs_url: [CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:[CUSTOM_HOST]/jobs?w=[WORKSPACE_ID] path:/jobs?view=list#top workspace:{[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}]
        -
        -=== Profile no_workspace_id
        -
        ->>> [CLI] bundle debug render-template-schema ./urls --profile no_workspace_id
        -{
        -  "welcome_message": "Initializing for [DATABRICKS_URL]",
        -  "success_message": "Open [DATABRICKS_URL]/jobs?view=list#top",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[DATABRICKS_URL]/jobs"
        -    },
        -    "path": {
        -      "description": "Path to open on [DATABRICKS_HOST]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        -
        ->>> [CLI] bundle init ./urls --profile no_workspace_id
        -Initializing for [DATABRICKS_URL]
        -Open [DATABRICKS_URL]/jobs?view=list#top
        -workspace_host: [DATABRICKS_URL]
        -Hostname: [DATABRICKS_HOST]
        -URL: [DATABRICKS_URL]
        -URL "/jobs": [DATABRICKS_URL]/jobs
        -URL "/jobs?view=list#top": [DATABRICKS_URL]/jobs?view=list#top
        -jobs_url: [DATABRICKS_URL]/jobs
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:[DATABRICKS_URL]/jobs path:/jobs?view=list#top workspace:{[DATABRICKS_HOST] [DATABRICKS_URL]  }]
        -
        -=== Rerender and init with edited inputs
        -
        ->>> [CLI] bundle debug render-template-schema ./urls --profile workspace_custom_host --input-file input.edited.json
        -{
        -  "welcome_message": "Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]",
        -  "success_message": "Open [CUSTOM_HOST]/pipelines?tab=all&w=[WORKSPACE_ID]",
        -  "properties": {
        -    "jobs_url": {
        -      "description": "Jobs page",
        -      "default": "[CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]"
        -    },
        -    "path": {
        -      "description": "Path to open on [CUSTOM_HOSTNAME]",
        -      "default": "/jobs?view=list#top"
        -    }
        -  }
        -}
        -
        ->>> [CLI] bundle init ./urls --profile workspace_custom_host --config-file input.edited.json
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Open [CUSTOM_HOST]/pipelines?tab=all&w=[WORKSPACE_ID]
        -workspace_host: [CUSTOM_HOST]
        -Hostname: [CUSTOM_HOSTNAME]
        -URL: [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -URL "/jobs": [CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]
        -URL "/pipelines?tab=all": [CUSTOM_HOST]/pipelines?tab=all&w=[WORKSPACE_ID]
        -jobs_url: https://example.test/my-jobs
        -Root keys: jobs_url path workspace
        -Root data: map[jobs_url:https://example.test/my-jobs path:/pipelines?tab=all workspace:{[CUSTOM_HOSTNAME] [CUSTOM_HOST] [WORKSPACE_ID] [WORKSPACE_ID]}]
        -
        -=== Invalid URL paths
        -
        ->>> musterr [CLI] bundle init ./urls --profile workspace_custom_host --config-file input.absolute-url.json
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Error: failed to compute file content for urls.txt.tmpl. template: :6:25: executing "" at <$ws.URL>: error calling URL: workspace URL path "https://other.test/jobs" must be relative to the workspace host
        -
        ->>> musterr [CLI] bundle init ./urls --profile workspace_custom_host --config-file input.workspace-selector.json
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Error: failed to compute file content for urls.txt.tmpl. template: :6:25: executing "" at <$ws.URL>: error calling URL: workspace URL path "/jobs?o=123" must not set the "o" query parameter, the workspace is selected by the profile
        -
        ->>> musterr [CLI] bundle init ./urls --profile workspace_custom_host --config-file input.semicolon.json
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Error: failed to compute file content for urls.txt.tmpl. template: :6:25: executing "" at <$ws.URL>: error calling URL: failed to parse query of workspace URL path "/jobs?w=999;x=1": invalid semicolon separator in query
        -
        -=== Workspace ID from environment variables
        -
        ->>> DATABRICKS_CONFIG_FILE=/dev/null DATABRICKS_HOST=[CUSTOM_HOST] DATABRICKS_WORKSPACE_ID=[WORKSPACE_ID] [CLI] bundle init ./urls
        -Initializing for [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -Open [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top
        -URL: [CUSTOM_HOST]?w=[WORKSPACE_ID]
        -URL "/jobs": [CUSTOM_HOST]/jobs?w=[WORKSPACE_ID]
        -URL "/jobs?view=list#top": [CUSTOM_HOST]/jobs?view=list&w=[WORKSPACE_ID]#top
        -
        -=== Workspace ID from the bundle in the working directory
        -
        ->>> [CLI] bundle init ../urls
        -Initializing for [DATABRICKS_URL]?w=[WORKSPACE_ID]
        -Open [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top
        -URL: [DATABRICKS_URL]?w=[WORKSPACE_ID]
        -URL "/jobs": [DATABRICKS_URL]/jobs?w=[WORKSPACE_ID]
        -URL "/jobs?view=list#top": [DATABRICKS_URL]/jobs?view=list&w=[WORKSPACE_ID]#top
        -
        -=== ID
        -
        ->>> [CLI] bundle init ./id --profile workspace_classic
        -✨ Successfully initialized template
        -ID: [WORKSPACE_ID]
        -
        ->>> [CLI] bundle init ./id --profile workspace_custom_host
        -✨ Successfully initialized template
        -ID: [WORKSPACE_ID]
        -
        ->>> musterr [CLI] bundle init ./id --profile no_workspace_id
        -Error: failed to compute file content for id.txt.tmpl. template: :1:17: executing "" at <.workspace.ID>: error calling ID: cannot determine workspace ID, please set workspace_id in the configuration profile or the DATABRICKS_WORKSPACE_ID environment variable
        -
... (2 more lines truncated, raise DATABRICKS_CLI_TEST_MAX_LOG to see more)

Templates get the workspace of the selected profile as .workspace, in
template files and in schema rendering. It has Hostname, ID and URL.

URL adds ?w=<id> when a profile, an environment variable, or the bundle in
the working directory sets the workspace ID, so that a host shared by
several workspaces selects the right one. An ID that the SDK resolved from
host metadata is not added, so the host still matches a profile without
workspace_id under strict profile matching. ID fails when the ID is
unknown, and doesn't make a request to find it.

A workspace input declared in the schema takes precedence.

Co-authored-by: Isaac <no-reply@databricks.com>
@pavloKozlov
pavloKozlov force-pushed the workspace-context-template-data branch from b931f85 to 5f2f6db Compare November 4, 2026 15:41
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

✅ Integration test report

Commit: ea56a04

Run: 42041557551

Env ✅​pass 🙈​skip Time
✅​ aws linux-2core-8gb 271 17 5:01
✅​ aws-windows-latest-4core-16gb 273 15 4:18
✅​ azure linux-2core-8gb 270 17 5:09
✅​ azure-windows-latest-4core-16gb 272 15 4:16
✅​ gcp linux-2core-8gb 271 17 5:27
✅​ gcp-windows-latest-4core-16gb 273 15 3:45
Top 3 slowest tests (at least 2 minutes):
duration env testname
3:02 aws-windows-latest-4core-16gb TestAccept
2:58 azure-windows-latest-4core-16gb TestAccept
2:58 gcp-windows-latest-4core-16gb TestAccept

pavloKozlov and others added 3 commits November 4, 2026 16:12
Strict profile matching compares the workspace ID in the bundle host with
the profile's workspace_id and doesn't read it from an adb-<id> hostname.
Without ?w=, a profile with workspace_id on such a host didn't match the
generated host. URL no longer uses workspaceurls.WorkspaceBaseURL, which
skips ?w= there, so that package is unchanged.

Co-authored-by: Isaac <no-reply@databricks.com>
RenderSchema skipped a property when the input file had a value for it, so
its default came back as template text. A caller that renders the schema
again with the current inputs got, for example, the raw .workspace.URL
expression. The default is now rendered, and the input value is still the
one used for the following properties.

Co-authored-by: Isaac <no-reply@databricks.com>
Hostname is now the host name only, without the port, like url.URL.Hostname.
Databricks hosts don't have an explicit port, so this changes nothing for
them.

Co-authored-by: Isaac <no-reply@databricks.com>
@pavloKozlov
pavloKozlov marked this pull request as ready for review November 5, 2026 09:35
@pavloKozlov
pavloKozlov requested review from a team as code owners November 5, 2026 09:35
This reverts 51344db. Templates that strip the scheme from
workspace_host get host:port, so keeping the port gives them the same
value with .workspace.Hostname. Databricks hosts don't have an explicit
port, so for them both are the same.

Co-authored-by: Isaac <no-reply@databricks.com>
@pavloKozlov
pavloKozlov added this pull request to the merge queue Nov 6, 2026
Merged via the queue into main with commit a53af21 Nov 6, 2026
28 checks passed
@pavloKozlov
pavloKozlov deleted the workspace-context-template-data branch November 6, 2026 10:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

DABs DABs related issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants