Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
3 contributors

Users who have contributed to this file

@damccorm @stephenmichaelf @sandermvanvliet
138 lines (126 sloc) 5.84 KB
import fs = require('fs');
import path = require('path');
import os = require('os');
import tl = require('vsts-task-lib/task');
import tr = require('vsts-task-lib/toolrunner');
var uuidV4 = require('uuid/v4');
async function run() {
try {
tl.setResourcePath(path.join(__dirname, 'task.json'));
// Get inputs.
let input_errorActionPreference: string = tl.getInput('errorActionPreference', false) || 'Stop';
switch (input_errorActionPreference.toUpperCase()) {
case 'STOP':
case 'CONTINUE':
case 'SILENTLYCONTINUE':
break;
default:
throw new Error(tl.loc('JS_InvalidErrorActionPreference', input_errorActionPreference));
}
let input_failOnStderr = tl.getBoolInput('failOnStderr', false);
let input_ignoreLASTEXITCODE = tl.getBoolInput('ignoreLASTEXITCODE', false);
let input_workingDirectory = tl.getPathInput('workingDirectory', /*required*/ true, /*check*/ true);
let input_filePath: string;
let input_arguments: string;
let input_script: string;
let input_targetType: string = tl.getInput('targetType') || '';
if (input_targetType.toUpperCase() == 'FILEPATH') {
input_filePath = tl.getPathInput('filePath', /*required*/ true);
if (!tl.stats(input_filePath).isFile() || !input_filePath.toUpperCase().match(/\.PS1$/)) {
throw new Error(tl.loc('JS_InvalidFilePath', input_filePath));
}
input_arguments = tl.getInput('arguments') || '';
}
else if(input_targetType.toUpperCase() == 'INLINE') {
input_script = tl.getInput('script', false) || '';
}
else {
throw new Error(tl.loc('PS_InvalidTargetType', input_targetType));
}
// Generate the script contents.
console.log(tl.loc('GeneratingScript'));
let contents: string[] = [];
contents.push(`$ErrorActionPreference = '${input_errorActionPreference}'`);
if (input_targetType.toUpperCase() == 'FILEPATH') {
contents.push(`. '${input_filePath.replace("'", "''")}' ${input_arguments}`.trim());
console.log(tl.loc('JS_FormattedCommand', contents[contents.length - 1]));
}
else {
contents.push(input_script);
}
if (!input_ignoreLASTEXITCODE) {
contents.push(`if (!(Test-Path -LiteralPath variable:\LASTEXITCODE)) {`);
contents.push(` Write-Host '##vso[task.debug]$LASTEXITCODE is not set.'`);
contents.push(`} else {`);
contents.push(` Write-Host ('##vso[task.debug]$LASTEXITCODE: {0}' -f $LASTEXITCODE)`);
contents.push(` exit $LASTEXITCODE`);
contents.push(`}`);
}
// Write the script to disk.
tl.assertAgent('2.115.0');
let tempDirectory = tl.getVariable('agent.tempDirectory');
tl.checkPath(tempDirectory, `${tempDirectory} (agent.tempDirectory)`);
let filePath = path.join(tempDirectory, uuidV4() + '.ps1');
await fs.writeFile(
filePath,
'\ufeff' + contents.join(os.EOL), // Prepend the Unicode BOM character.
{ encoding: 'utf8' }); // Since UTF8 encoding is specified, node will
// // encode the BOM into its UTF8 binary sequence.
// Run the script.
//
// Note, prefer "pwsh" over "powershell". At some point we can remove support for "powershell".
//
// Note, use "-Command" instead of "-File" to match the Windows implementation. Refer to
// comment on Windows implementation for an explanation why "-Command" is preferred.
console.log('========================== Starting Command Output ===========================');
let powershell = tl.tool(tl.which('pwsh') || tl.which('powershell') || tl.which('pwsh', true))
.arg('-NoLogo')
.arg('-NoProfile')
.arg('-NonInteractive')
.arg('-Command')
.arg(`. '${filePath.replace("'", "''")}'`);
let options = <tr.IExecOptions>{
cwd: input_workingDirectory,
failOnStdErr: false,
errStream: process.stdout, // Direct all output to STDOUT, otherwise the output may appear out
outStream: process.stdout, // of order since Node buffers it's own STDOUT but not STDERR.
ignoreReturnCode: true
};
// Listen for stderr.
let stderrFailure = false;
const aggregatedStderr: string[] = [];
if (input_failOnStderr) {
powershell.on('stderr', (data: Buffer) => {
stderrFailure = true;
// Truncate to at most 10 error messages
if (aggregatedStderr.length < 10) {
// Truncate to at most 1000 bytes
if (data.length > 1000) {
aggregatedStderr.push(`${data.toString('utf8', 0, 1000)}<truncated>`);
} else {
aggregatedStderr.push(data.toString('utf8'));
}
} else if (aggregatedStderr.length === 10) {
aggregatedStderr.push('Additional writes to stderr truncated');
}
});
}
// Run bash.
let exitCode: number = await powershell.exec(options);
// Fail on exit code.
if (exitCode !== 0) {
tl.setResult(tl.TaskResult.Failed, tl.loc('JS_ExitCode', exitCode));
}
// Fail on stderr.
if (stderrFailure) {
tl.setResult(tl.TaskResult.Failed, tl.loc('JS_Stderr'));
aggregatedStderr.forEach((err: string) => {
tl.error(err);
});
}
}
catch (err) {
tl.setResult(tl.TaskResult.Failed, err.message || 'run() failed');
}
}
run();
You can’t perform that action at this time.