Skip to content

Commit c8fd2e2

Browse files
author
Waldek Herka
committed
Adding inContainer input parameter to be able to switch between direct and in-container mode of execution
1 parent 99c7fe7 commit c8fd2e2

File tree

3 files changed

+67
-4
lines changed

3 files changed

+67
-4
lines changed

action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ inputs:
99
description: 'Azure CLI version to be used to execute the script. If not provided, latest version is used'
1010
required: false
1111
default: 'agentazcliversion'
12+
inContainer:
13+
description: 'Execute the commands in container'
14+
required: false
15+
default: true
1216
branding:
1317
icon: 'login.svg'
1418
color: 'blue'

dist/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main.ts

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const cpExec = util.promisify(require('child_process').exec);
1010
import { createScriptFile, TEMP_DIRECTORY, NullOutstreamStringWritable, deleteFile, getCurrentTime, checkIfEnvironmentVariableIsOmitted } from './utils';
1111

1212
const START_SCRIPT_EXECUTION_MARKER: string = "Starting script execution via docker image mcr.microsoft.com/azure-cli:";
13+
const START_SCRIPT_DIRECT_EXECUTION_MARKER: string = "Starting script execution via az in the agent:";
1314
const AZ_CLI_VERSION_DEFAULT_VALUE = 'agentazcliversion'
1415
const prefix = !!process.env.AZURE_HTTP_USER_AGENT ? `${process.env.AZURE_HTTP_USER_AGENT}` : "";
1516

@@ -21,13 +22,15 @@ export async function main() {
2122

2223
var scriptFileName: string = '';
2324
const CONTAINER_NAME = `MICROSOFT_AZURE_CLI_${getCurrentTime()}_CONTAINER`;
25+
let executingInContainer: boolean = false;
2426
try {
2527
if (process.env.RUNNER_OS != 'Linux') {
2628
throw new Error('Please use Linux-based OS as a runner.');
2729
}
2830

2931
let inlineScript: string = core.getInput('inlineScript', { required: true });
3032
let azcliversion: string = core.getInput('azcliversion', { required: false }).trim().toLowerCase();
33+
let inContainer: boolean = core.getInput('inContainer', { required: false }).trim().toLowerCase() === 'true';
3134

3235
if (azcliversion == AZ_CLI_VERSION_DEFAULT_VALUE) {
3336
try {
@@ -48,9 +51,22 @@ export async function main() {
4851
core.error('Please enter a valid script.');
4952
throw new Error('Please enter a valid script.')
5053
}
54+
if (inContainer == false) {
55+
try {
56+
inlineScript = ` set -e >&2; echo '${START_SCRIPT_DIRECT_EXECUTION_MARKER}' >&2; ${inlineScript}`;
57+
scriptFileName = await createScriptFile(inlineScript);
58+
let args: string[] = ["--noprofile", "--norc", "-e", `${TEMP_DIRECTORY}/${scriptFileName}`];
59+
console.log(`${START_SCRIPT_DIRECT_EXECUTION_MARKER}`);
60+
await executeBashCommand(args);
61+
console.log("az script ran successfully.");
62+
return;
63+
} catch (err) {
64+
console.log('Failed to fetch az cli version from agent. Reverting back to execution in container.')
65+
}
66+
}
67+
executingInContainer = true;
5168
inlineScript = ` set -e >&2; echo '${START_SCRIPT_EXECUTION_MARKER}' >&2; ${inlineScript}`;
5269
scriptFileName = await createScriptFile(inlineScript);
53-
5470
/*
5571
For the docker run command, we are doing the following
5672
- Set the working directory for docker continer
@@ -75,6 +91,7 @@ export async function main() {
7591
console.log(`${START_SCRIPT_EXECUTION_MARKER}${azcliversion}`);
7692
await executeDockerCommand(args);
7793
console.log("az script ran successfully.");
94+
7895
}
7996
catch (error) {
8097
core.error(error);
@@ -84,8 +101,10 @@ export async function main() {
84101
// clean up
85102
const scriptFilePath: string = path.join(TEMP_DIRECTORY, scriptFileName);
86103
await deleteFile(scriptFilePath);
87-
console.log("cleaning up container...");
88-
await executeDockerCommand(["rm", "--force", CONTAINER_NAME], true);
104+
if (executingInContainer) {
105+
console.log("cleaning up container...");
106+
await executeDockerCommand(["rm", "--force", CONTAINER_NAME], true);
107+
}
89108
}
90109
};
91110

@@ -157,3 +176,43 @@ const executeDockerCommand = async (args: string[], continueOnError: boolean = f
157176
core.warning(errorStream)
158177
}
159178
}
179+
180+
const executeBashCommand = async (args: string[], continueOnError: boolean = false): Promise<void> => {
181+
182+
const bash: string = await io.which("bash", true);
183+
var errorStream: string = '';
184+
var shouldOutputErrorStream: boolean = false;
185+
var execOptions: any = {
186+
outStream: new NullOutstreamStringWritable({ decodeStrings: false }),
187+
listeners: {
188+
stdout: (data: any) => console.log(data.toString()), //to log the script output while the script is running.
189+
errline: (data: string) => {
190+
if (!shouldOutputErrorStream) {
191+
errorStream += data + os.EOL;
192+
}
193+
else {
194+
console.log(data);
195+
}
196+
if (data.trim() === START_SCRIPT_EXECUTION_MARKER) {
197+
shouldOutputErrorStream = true;
198+
errorStream = ''; // Flush the container logs. After this, script error logs will be tracked.
199+
}
200+
}
201+
}
202+
};
203+
var exitCode;
204+
try {
205+
exitCode = await exec.exec(bash, args, execOptions);
206+
} catch (error) {
207+
if (!continueOnError) {
208+
throw error;
209+
}
210+
core.warning(error);
211+
}
212+
finally {
213+
if (exitCode !== 0 && !continueOnError) {
214+
throw new Error(errorStream || 'az cli script failed.');
215+
}
216+
core.warning(errorStream)
217+
}
218+
}

0 commit comments

Comments
 (0)