Skip to content

Commit 7afb87f

Browse files
authored
Use "bundle sync" instead of "bundle deploy" for remote run commands (#1401)
## Changes Also changes the continuous sync logic to use the `bundle sync` command instead of the `sync`. Depends on the CLI PR: databricks/cli#1853 Sync E2E tests will be failing until we update the CLI ## Tests Manual and existing unit and e2e tests
1 parent 05114fa commit 7afb87f

File tree

8 files changed

+105
-64
lines changed

8 files changed

+105
-64
lines changed

packages/databricks-vscode/src/bundle/models/BundleRemoteStateModel.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,25 @@ export class BundleRemoteStateModel extends BaseModelWithStateCache<BundleRemote
103103
);
104104
}
105105

106+
@Mutex.synchronise("mutex")
107+
public async sync(token: CancellationToken) {
108+
if (this.target === undefined) {
109+
throw new Error("Target is undefined");
110+
}
111+
if (this.authProvider === undefined) {
112+
throw new Error("No authentication method is set");
113+
}
114+
115+
await this.cli.bundleSync(
116+
this.target,
117+
this.authProvider,
118+
this.workspaceFolder,
119+
this.workspaceConfigs.databrickscfgLocation,
120+
this.logger,
121+
token
122+
);
123+
}
124+
106125
public async getRunCommand(resourceKey: string) {
107126
if (this.target === undefined) {
108127
throw new Error("Target is undefined");

packages/databricks-vscode/src/cli/CliWrapper.test.ts

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
import * as assert from "assert";
22
import {Uri} from "vscode";
3-
import {
4-
LocalUri,
5-
RemoteUri,
6-
SyncDestinationMapper,
7-
} from "../sync/SyncDestination";
83
import {workspaceConfigs} from "../vscode-objs/WorkspaceConfigs";
94
import {promisify} from "node:util";
105
import {execFile as execFileCb} from "node:child_process";
@@ -79,25 +74,16 @@ describe(__filename, function () {
7974
it("should create sync commands", async () => {
8075
const logFilePath = getTempLogFilePath();
8176
const cli = createCliWrapper(logFilePath);
82-
const mapper = new SyncDestinationMapper(
83-
new LocalUri(Uri.file("/user/project")),
84-
new RemoteUri(
85-
Uri.from({
86-
scheme: "wsfs",
87-
path: "/Repos/[email protected]/project",
88-
})
89-
)
90-
);
9177

92-
const syncCommand = `${cliPath} sync . /Repos/[email protected]/project --watch --output json`;
78+
const syncCommand = `${cliPath} bundle sync --watch --output json`;
9379
const loggingArgs = `--log-level debug --log-file ${logFilePath} --log-format json`;
94-
let {command, args} = cli.getSyncCommand(mapper, "incremental");
80+
let {command, args} = cli.getSyncCommand("incremental");
9581
assert.equal(
9682
[command, ...args].join(" "),
9783
[syncCommand, loggingArgs].join(" ")
9884
);
9985

100-
({command, args} = cli.getSyncCommand(mapper, "full"));
86+
({command, args} = cli.getSyncCommand("full"));
10187
assert.equal(
10288
[command, ...args].join(" "),
10389
[syncCommand, loggingArgs, "--full"].join(" ")
@@ -106,7 +92,7 @@ describe(__filename, function () {
10692
const configsSpy = spy(workspaceConfigs);
10793
mocks.push(configsSpy);
10894
when(configsSpy.loggingEnabled).thenReturn(false);
109-
({command, args} = cli.getSyncCommand(mapper, "incremental"));
95+
({command, args} = cli.getSyncCommand("incremental"));
11096
assert.equal([command, ...args].join(" "), syncCommand);
11197
});
11298

packages/databricks-vscode/src/cli/CliWrapper.ts

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
commands,
1212
CancellationToken,
1313
} from "vscode";
14-
import {SyncDestinationMapper} from "../sync/SyncDestination";
1514
import {workspaceConfigs} from "../vscode-objs/WorkspaceConfigs";
1615
import {promisify} from "node:util";
1716
import {logging} from "@databricks/databricks-sdk";
@@ -335,14 +334,10 @@ export class CliWrapper {
335334
/**
336335
* Constructs the databricks sync command
337336
*/
338-
getSyncCommand(
339-
syncDestination: SyncDestinationMapper,
340-
syncType: SyncType
341-
): Command {
337+
getSyncCommand(syncType: SyncType): Command {
342338
const args = [
339+
"bundle",
343340
"sync",
344-
".",
345-
syncDestination.remoteUri.path,
346341
"--watch",
347342
"--output",
348343
"json",
@@ -664,6 +659,32 @@ export class CliWrapper {
664659
);
665660
}
666661

662+
async bundleSync(
663+
target: string,
664+
authProvider: AuthProvider,
665+
workspaceFolder: Uri,
666+
configfilePath?: string,
667+
logger?: logging.NamedLogger,
668+
token?: CancellationToken
669+
) {
670+
await commands.executeCommand("databricks.bundle.showLogs");
671+
return await runBundleCommand(
672+
"sync",
673+
this.cliPath,
674+
["bundle", "sync", "--target", target, "--output", "text"],
675+
workspaceFolder,
676+
{
677+
start: `Uploading bundle assets for target ${target}...`,
678+
end: "Bundle assets uploaded successfully.",
679+
error: "Failed to upload bundle assets.",
680+
},
681+
await this.getBundleCommandEnvVars(authProvider, configfilePath),
682+
logger,
683+
{},
684+
token
685+
);
686+
}
687+
667688
async getBundleRunCommand(
668689
target: string,
669690
authProvider: AuthProvider,

packages/databricks-vscode/src/cli/SyncTasks.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,12 @@ export class LazyCustomSyncTerminal extends CustomSyncTerminal {
249249
Object.defineProperties(this, {
250250
cmd: {
251251
get: () => {
252-
return this.getSyncCommand(ctx).command;
252+
return this.getSyncCommand().command;
253253
},
254254
},
255255
args: {
256256
get: () => {
257-
return this.getSyncCommand(ctx).args;
257+
return this.getSyncCommand().args;
258258
},
259259
},
260260
options: {
@@ -311,21 +311,12 @@ export class LazyCustomSyncTerminal extends CustomSyncTerminal {
311311
} as SpawnOptions;
312312
}
313313

314-
@withLogContext(Loggers.Extension)
315-
getSyncCommand(@context ctx?: Context): Command {
314+
getSyncCommand(): Command {
316315
if (this.command) {
317316
return this.command;
318317
}
319-
const syncDestination = this.connection.syncDestinationMapper;
320-
321-
if (!syncDestination) {
322-
throw this.showErrorAndKillThis(
323-
"Can't start sync: Databricks synchronization destination not configured!",
324-
ctx
325-
);
326-
}
327318

328-
this.command = this.cli.getSyncCommand(syncDestination, this.syncType);
319+
this.command = this.cli.getSyncCommand(this.syncType);
329320

330321
return this.command;
331322
}

packages/databricks-vscode/src/run/DatabricksRuntime.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,9 @@ export class DatabricksRuntime implements Disposable {
137137
throw new Error("No sync destination found");
138138
}
139139

140-
log("Deploying assets to databricks workspace...");
140+
log("Uploading assets to databricks workspace...");
141141
this.state = "SYNCING";
142-
await this.bundleCommands.deploy();
142+
await this.bundleCommands.sync();
143143

144144
await commands.executeCommand("workbench.panel.repl.view.focus");
145145

packages/databricks-vscode/src/run/WorkflowRunner.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,11 @@ export class WorkflowRunner implements Disposable {
8989
}
9090

9191
try {
92-
await this.bundleCommands.deploy();
92+
await this.bundleCommands.sync();
9393
} catch (e: unknown) {
9494
if (e instanceof Error) {
9595
panel.showError({
96-
message: `Can't deploy assets to databricks workspace. \nReason: ${e.message}`,
96+
message: `Can't upload assets to databricks workspace. \nReason: ${e.message}`,
9797
});
9898
}
9999
return;

packages/databricks-vscode/src/test/e2e/run_files.e2e.ts

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -46,33 +46,14 @@ describe("Run files", async function () {
4646
await openFile("hello.py");
4747
});
4848

49-
it("should run a python file on a cluster", async () => {
50-
const workbench = await driver.getWorkbench();
51-
await executeCommandWhenAvailable("Databricks: Upload and Run File");
52-
53-
const debugOutput = await workbench
54-
.getBottomBar()
55-
.openDebugConsoleView();
56-
57-
while (true) {
58-
await sleep(2000);
59-
const text = await (await debugOutput.elem).getHTML();
60-
if (text && text.includes("hello world")) {
61-
break;
62-
}
63-
}
64-
});
65-
6649
it("should cancel a run during deployment", async () => {
6750
const workbench = await driver.getWorkbench();
6851
await executeCommandWhenAvailable("Databricks: Upload and Run File");
6952
await browser.waitUntil(async () => {
7053
const notifications = await workbench.getNotifications();
7154
for (const notification of notifications) {
7255
const message = await notification.getMessage();
73-
if (message.includes("Deploying")) {
74-
// Make sure the CLI is actually spawned before cancelling
75-
await sleep(1000);
56+
if (message.includes("Uploading bundle assets")) {
7657
await notification.takeAction("Cancel");
7758
return true;
7859
}
@@ -92,9 +73,25 @@ describe("Run files", async function () {
9273
}
9374
});
9475

95-
it("should run a python file as a workflow", async () => {
76+
it("should run a python file on a cluster", async () => {
9677
const workbench = await driver.getWorkbench();
97-
await workbench.executeQuickPick("Databricks: Run File as Workflow");
78+
await executeCommandWhenAvailable("Databricks: Upload and Run File");
79+
80+
const debugOutput = await workbench
81+
.getBottomBar()
82+
.openDebugConsoleView();
83+
84+
while (true) {
85+
await sleep(2000);
86+
const text = await (await debugOutput.elem).getHTML();
87+
if (text && text.includes("hello world")) {
88+
break;
89+
}
90+
}
91+
});
92+
93+
it("should run a python file as a workflow", async () => {
94+
await executeCommandWhenAvailable("Databricks: Run File as Workflow");
9895
await waitForWorkflowWebview("hello world");
9996
});
10097
});

packages/databricks-vscode/src/ui/bundle-resource-explorer/BundleCommands.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,33 @@ export class BundleCommands implements Disposable {
8585

8686
private deployMutex = new Mutex();
8787

88+
@Mutex.synchronise("deployMutex")
89+
async sync() {
90+
try {
91+
this.whenContext.setDeploymentState("deploying");
92+
await window.withProgress(
93+
{
94+
location: ProgressLocation.Notification,
95+
title: "Uploading bundle assets",
96+
cancellable: true,
97+
},
98+
async (progress, token) => {
99+
await this.bundleRemoteStateModel.sync(token);
100+
}
101+
);
102+
} catch (e) {
103+
if (!(e instanceof Error)) {
104+
throw e;
105+
}
106+
if (e instanceof ProcessError) {
107+
e.showErrorMessage("Error synchronising bundle assets.");
108+
}
109+
throw e;
110+
} finally {
111+
this.whenContext.setDeploymentState("idle");
112+
}
113+
}
114+
88115
@Mutex.synchronise("deployMutex")
89116
async deploy(force = false) {
90117
try {

0 commit comments

Comments
 (0)