From ec321696c85b6066dd976589d118360f644d3d4d Mon Sep 17 00:00:00 2001 From: Stuart Leeks Date: Thu, 9 Mar 2023 18:58:15 +0000 Subject: [PATCH] Update to run 'devcontainer exec' without JSON parsing output --- azdo-task/DevcontainersCi/src/main.ts | 11 +++++----- common/src/dev-container-cli.ts | 29 ++++++++++++++++++++------- github-action/src/main.ts | 15 +++++++------- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/azdo-task/DevcontainersCi/src/main.ts b/azdo-task/DevcontainersCi/src/main.ts index 1c1920f59..93d040d43 100644 --- a/azdo-task/DevcontainersCi/src/main.ts +++ b/azdo-task/DevcontainersCi/src/main.ts @@ -152,13 +152,14 @@ export async function runMain(): Promise { } }; const execResult = await devcontainer.exec(execArgs, execLog); - if (execResult.outcome !== 'success') { + if (execResult !== 0) { console.log( - `### ERROR: Dev container exec: ${execResult.message} (exit code: ${execResult.code})\n${execResult.description}`, + `### ERROR: Dev container exec failed (exit code: ${execResult})`, + ); + task.setResult( + TaskResult.Failed, + `Dev container exec failed (exit code: ${execResult})`, ); - task.setResult(TaskResult.Failed, execResult.message); - } - if (execResult.outcome !== 'success') { return; } if (execLogString.length >= 25000) { diff --git a/common/src/dev-container-cli.ts b/common/src/dev-container-cli.ts index 96422affc..3afec0127 100644 --- a/common/src/dev-container-cli.ts +++ b/common/src/dev-container-cli.ts @@ -109,11 +109,12 @@ function parseCliOutput(value: string): T | DevContainerCliError { } } -async function runSpecCli(options: { +async function runSpecCliJsonCommand(options: { args: string[]; log: (data: string) => void; env?: NodeJS.ProcessEnv; }) { + // For JSON commands, pass stderr on to logging but capture stdout and parse the JSON response let stdout = ''; const spawnOptions: SpawnOptions = { log: data => (stdout += data), @@ -126,6 +127,22 @@ async function runSpecCli(options: { return parseCliOutput(stdout); } +async function runSpecCliNonJsonCommand(options: { + args: string[]; + log: (data: string) => void; + env?: NodeJS.ProcessEnv; +}) { + // For non-JSON commands, pass both stdout and stderr on to logging + const spawnOptions: SpawnOptions = { + log: data => options.log(data), + err: data => options.log(data), + env: options.env ? {...process.env, ...options.env} : process.env, + }; + const command = getSpecCliInfo().command; + console.log(`About to run ${command} ${options.args.join(' ')}`); // TODO - take an output arg to allow GH to use core.info + const result = await spawn(command, options.args, spawnOptions); + return result.code +} export interface DevContainerCliSuccessResult { outcome: 'success'; @@ -172,7 +189,7 @@ async function devContainerBuild( commandArgs.push('--cache-from', cacheFrom), ); } - return await runSpecCli({ + return await runSpecCliJsonCommand({ args: commandArgs, log, env: {DOCKER_BUILDKIT: '1', COMPOSE_DOCKER_CLI_BUILD: '1'}, @@ -219,15 +236,13 @@ async function devContainerUp( commandArgs.push('--mount', mount), ); } - return await runSpecCli({ + return await runSpecCliJsonCommand({ args: commandArgs, log, env: {DOCKER_BUILDKIT: '1', COMPOSE_DOCKER_CLI_BUILD: '1'}, }); } -export interface DevContainerCliExecResult - extends DevContainerCliSuccessResult {} export interface DevContainerCliExecArgs { workspaceFolder: string; command: string[]; @@ -237,14 +252,14 @@ export interface DevContainerCliExecArgs { async function devContainerExec( args: DevContainerCliExecArgs, log: (data: string) => void, -): Promise { +): Promise { // const remoteEnvArgs = args.env ? args.env.flatMap(e=> ["--remote-env", e]): []; // TODO - test flatMap again const remoteEnvArgs = getRemoteEnvArray(args.env); const commandArgs = ["exec", "--workspace-folder", args.workspaceFolder, ...remoteEnvArgs, ...args.command]; if (args.userDataFolder) { commandArgs.push("--user-data-folder", args.userDataFolder); } - return await runSpecCli({ + return await runSpecCliNonJsonCommand({ args: commandArgs, log, env: {DOCKER_BUILDKIT: '1', COMPOSE_DOCKER_CLI_BUILD: '1'}, diff --git a/github-action/src/main.ts b/github-action/src/main.ts index df7fa1b68..eca23d88b 100644 --- a/github-action/src/main.ts +++ b/github-action/src/main.ts @@ -177,12 +177,11 @@ export async function runMain(): Promise { execLogString += message; } }; - const result = await devcontainer.exec(args, execLog); - if (result.outcome !== 'success') { - core.error( - `Dev container exec: ${result.message} (exit code: ${result.code})\n${result.description}`, - ); - core.setFailed(result.message); + const exitCode = await devcontainer.exec(args, execLog); + if (exitCode !== 0) { + const errorMessage = `Dev container exec failed: (exit code: ${exitCode})`; + core.error(errorMessage); + core.setFailed(errorMessage); } core.setOutput('runCmdOutput', execLogString); if (Buffer.byteLength(execLogString, 'utf-8') > 1000000) { @@ -190,10 +189,10 @@ export async function runMain(): Promise { execLogString += 'TRUNCATED TO 1 MB MAX OUTPUT SIZE'; } core.setOutput('runCmdOutput', execLogString); - return result; + return exitCode; }, ); - if (execResult.outcome !== 'success') { + if (execResult !== 0) { return; } } else {