Search code examples
visual-studio-codevscode-extensions

How to await a build task in a VS Code extension?


let result = await vscode.commands.executeCommand('workbench.action.tasks.build');

resolves immediately.

How can I await a build task with VS Code API?


Solution

  • I figured it out! Tasks cannot be awaited from vscode.tasks.executeTask, but we can await vscode.tasks.onDidEndTask and check if ended task is our task.

    async function executeBuildTask(task: vscode.Task) {
        const execution = await vscode.tasks.executeTask(task);
    
        return new Promise<void>(resolve => {
            let disposable = vscode.tasks.onDidEndTask(e => {
                if (e.execution.task.group === vscode.TaskGroup.Build) {
                    disposable.dispose();
                    resolve();
                }
            });
        });
    }
    
    async function getBuildTasks() {
        return new Promise<vscode.Task[]>(resolve => {
            vscode.tasks.fetchTasks().then((tasks) => {
                resolve(tasks.filter((task) => task.group === vscode.TaskGroup.Build));
            });
        });
    }
    
    export function activate(context: vscode.ExtensionContext) {
        context.subscriptions.push(vscode.commands.registerCommand('extension.helloWorld', async () => {
            const buildTasks = await getBuildTasks();
            await executeBuildTask(buildTasks[0]);
        }));
    }
    

    Note that currently there is a bug #96643, which prevents us from doing a comparison of vscode.Task objects: if (e.execution.task === execution.task) { ... }