Skip to content

Commit

Permalink
Merge pull request #26 from microsoft/dev/chrisnielsen_recreateDebugDrop
Browse files Browse the repository at this point in the history
Dev/chrisnielsen recreate debug drop
  • Loading branch information
chrisnielsen-MS authored Mar 13, 2024
2 parents b936959 + 8f710eb commit fa0f8ba
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 3 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microsoft/security-devops-azdevops-task-lib",
"version": "1.10.1",
"version": "1.11.0",
"description": "Microsoft Security DevOps for Azure DevOps task library.",
"author": "Microsoft Corporation",
"license": "MIT",
Expand Down
141 changes: 141 additions & 0 deletions src/msdo-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as tl from 'azure-pipelines-task-lib/task';
import { IExecOptions } from "azure-pipelines-task-lib/toolrunner";
import * as common from './msdo-common';
import * as installer from './msdo-installer';
import AdmZip = require('adm-zip');

/**
* The default version of Guardian to install if no version is specified.
Expand Down Expand Up @@ -87,10 +88,23 @@ async function init() {
*/
export async function run(inputArgs: string[], successfulExitCodes: number[] = null, publish: boolean = true, publishArtifactName: string = null, telemetryEnvironment: string = 'azdevops'): Promise<void> {
let tool = null;
let debugDrop = common.parseBool(process.env.GDN_DEBUG_DROP);

let sarifFile: string = path.join(process.env.BUILD_STAGINGDIRECTORY, '.gdn', 'msdo.sarif');
tl.debug(`sarifFile = ${sarifFile}`);

const gdnTaskLibFolder = path.resolve(__dirname);
tl.debug(`gdnTaskLibFolder = ${gdnTaskLibFolder}`);

const nodeModulesFolder = path.dirname(path.dirname(gdnTaskLibFolder));
tl.debug(`nodeModulesFolder = ${nodeModulesFolder}`);

const taskFolder = path.dirname(nodeModulesFolder);
tl.debug(`taskFolder = ${taskFolder}`);

const debugFolder = path.join(taskFolder, 'debug');
tl.debug(`debugFolder = ${debugFolder}`);

try {

if (successfulExitCodes == null) {
Expand Down Expand Up @@ -140,6 +154,18 @@ export async function run(inputArgs: string[], successfulExitCodes: number[] = n

tool.arg('--telemetry-environment');
tool.arg(telemetryEnvironment);

// Include the debug drop option on the command line if applicable.
tl.debug(`GdnDebugDrop = ${debugDrop}`);
if (debugDrop)
{
const dropPathValue = path.join(taskFolder, 'debug');
tool.arg('--debug-drop').arg('--debug-drop-path').arg(dropPathValue);
const dropPathName = `GDN_DEBUGDROPPATH`;

tl.debug(`Debug Drop enabled. ${dropPathName}: ${dropPathValue}`);
process.env[dropPathName] = dropPathValue;
}
} catch (error) {
console.error('Exception occurred while initializing MSDO:');
tl.setResult(tl.TaskResult.Failed, error);
Expand All @@ -154,6 +180,9 @@ export async function run(inputArgs: string[], successfulExitCodes: number[] = n

tl.debug('Running Microsoft Security DevOps...');

// Ensure debug folder starts clean
cleanupDirectory(debugFolder);

let exitCode = await tool.exec(options);

let success = false;
Expand All @@ -164,6 +193,40 @@ export async function run(inputArgs: string[], successfulExitCodes: number[] = n
}
}

// Package up debug drop if applicable.
let debugStagingDir = '';
tl.debug(`GdnDebugDrop = ${debugDrop}`);
if (debugDrop) {
if (fs.existsSync(debugFolder)) {
tl.debug("Creating debug drop archive...");
let zippedOutput = getZippedFolder(debugFolder);

const taskFilePath = path.join(taskFolder, `task.json`);
tl.debug(`taskFilePath = ${taskFilePath}`);
const taskFile = require(taskFilePath);
const taskName = taskFile.name.toUpperCase();

const instanceDirectory = getInstanceDirectory();
debugStagingDir = path.join(instanceDirectory, '.gdn', 'debugdrop');
if (!fs.existsSync(debugStagingDir)) {
tl.debug(`Creating missing folder: ${debugStagingDir}`)
fs.mkdirSync(debugStagingDir)
}

let debugDropArtifact = path.join(debugStagingDir, `${taskName}_debug.zip`);
let dupeCount = 0;
while (fs.existsSync(debugDropArtifact)) {
dupeCount += 1;
debugDropArtifact = path.join(debugStagingDir, `${taskName}_${dupeCount}_debug.zip`)
}
fs.copyFileSync(zippedOutput, debugDropArtifact);
tl.debug(`Finished creating: ${debugDropArtifact}`);
tl.debug(`Cleaning up: ${path.join(taskFolder, 'debug')}`);
cleanupDirectory(path.join(taskFolder, 'debug'));
tl.debug(`Successfully cleaned up debug dump.`);
}
}

if (publish && fs.existsSync(sarifFile)) {
if (common.isNullOrWhiteSpace(publishArtifactName)) {
publishArtifactName = 'CodeAnalysisLogs';
Expand All @@ -172,10 +235,88 @@ export async function run(inputArgs: string[], successfulExitCodes: number[] = n
console.log(`##vso[artifact.upload artifactname=${publishArtifactName}]${sarifFile}`);
}

if (publish && fs.existsSync(debugStagingDir)) {
console.log(`##vso[artifact.upload artifactname=DebugDrop]${debugStagingDir}`);
}

if (!success) {
throw `MSDO CLI exited with an error exit code: ${exitCode}`;
}
} catch (error) {
tl.setResult(tl.TaskResult.Failed, error);
}
}

function getInstanceDirectory(): string {
let hostType = process.env.SYSTEM_HOSTTYPE;
if (hostType) {
hostType = hostType.toUpperCase();
}

if (hostType == "RELEASE") {
return process.env.AGENT_RELEASEDIRECTORY;
} else { // hostType == "BUILD" or default
return process.env.BUILD_SOURCESDIRECTORY;
}
}

function getZippedFolder(dir): string {
tl.debug(`Zipping up folder: ${dir}`)
let allPaths = getFilePathsRecursively(dir);
const zip = new AdmZip();
for (let filePath of allPaths) {
tl.debug(`Adding file to archive: ${filePath}`);
zip.addLocalFile(filePath);
}

let destPath = `${dir}.zip`;
tl.debug(`Writing to file: ${destPath}`)
zip.writeZip(destPath);
if (fs.existsSync(destPath)) {
tl.debug(`Successfully wrote file: ${destPath}`)
} else {
tl.debug(`Something went wrong! File does not exist: ${destPath}`)
}
return destPath;
}

// Returns a flat array of absolute paths to all files contained in the dir
function getFilePathsRecursively(dir) {
tl.debug(`Searching for files under dir: ${dir}`)
var files = [];
let fileList = fs.readdirSync(dir);
var remaining = fileList.length;
if (!remaining) return files;

for (let file of fileList) {
file = path.resolve(dir, file);
let stat = fs.statSync(file);
if (stat && stat.isDirectory()) {
let f = getFilePathsRecursively(file);
files = files.concat(f);
} else {
files.push(file);
}
if (!--remaining) {
return files;
}
}
}

function cleanupDirectory(dir) {
if (!fs.existsSync(dir)) return;

let items = fs.readdirSync(dir);

for (let item of items) {
item = path.resolve(dir, item)
let stat = fs.statSync(item);
if (stat && stat.isDirectory()) {
cleanupDirectory(item)
} else {
fs.unlinkSync(item);
}
}

fs.rmdirSync(dir);
}

0 comments on commit fa0f8ba

Please sign in to comment.