Skip to content

Commit

Permalink
fix: remove use of echo for snyk code flow
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterSchafer authored Mar 12, 2024
2 parents efda195 + 7598c24 commit fbf37b3
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .snyk
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ ignore:
SNYK-JS-INFLIGHT-6095116:
- '*':
reason: No upgrade available
expires: 2024-03-01T00:00:00.000Z
expires: 2024-06-01T00:00:00.000Z
created: 2023-12-04T08:42:17.557Z
patch: {}
66 changes: 66 additions & 0 deletions snykTask/src/__tests__/task-lib.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import * as fse from 'fs-extra';
import { generateSnykCodeResultsWithoutIssues } from '../index';
import { getSnykDownloadInfo, downloadExecutable } from '../install';

jest.setTimeout(120_000);

import stream = require('stream');

Expand All @@ -33,12 +37,29 @@ import {
doVulnerabilitiesExistForFailureThreshold,
} from '../task-lib';
import { TaskArgs } from '../task-args';
import { execSync } from 'child_process';

let tempFolder = '';
let snykCliPath = '';

function getTestToken(): string {
if (process.env.SNYK_TOKEN === undefined) {
const output = execSync(snykCliPath + ' config get api');
return output.toString().trim();
}

return process.env.SNYK_TOKEN;
}

beforeAll(async () => {
tempFolder = await fse.promises.mkdtemp(
path.resolve(os.tmpdir(), 'snyk-azure-pipelines-task-test'),
);

const dlInfo = getSnykDownloadInfo(tl.getPlatform());
await downloadExecutable(tempFolder, dlInfo.snyk);

snykCliPath = path.resolve(tempFolder, dlInfo.snyk.filename);
});

afterEach(() => {
Expand Down Expand Up @@ -226,6 +247,51 @@ describe('getOptionsForSnykToHtml', () => {
});
});

describe('generateSnykCodeResultsWithoutIssues sends console output to file', () => {
it('basic test for generateSnykCodeResultsWithoutIssues()', async () => {
const taskArgs: TaskArgs = new TaskArgs({
failOnIssues: true,
});

taskArgs.testDirectory = path.join(
__dirname,
'..',
'..',
'test',
'fixtures',
'golang-no-code-issues',
);
console.debug(taskArgs.testDirectory);

const outputPath = path.join(
tempFolder,
'generateSnykCodeResultsWithoutIssues_test.json',
);
const testToken = getTestToken();

expect(fs.existsSync(outputPath)).toBeFalsy();

// call method under test
await generateSnykCodeResultsWithoutIssues(
snykCliPath,
taskArgs,
outputPath,
testToken,
);

// check expected output
const actualFileStat = fs.statSync(outputPath);
expect(actualFileStat.isFile()).toBeTruthy();
expect(actualFileStat.size).toBeGreaterThan(0);

const actualFileContent = fs.readFileSync(outputPath);
const obj = JSON.parse(actualFileContent.toString());
expect(obj).not.toBeNull();

console.debug(obj);
});
});

test('formatDate gives format we want for the report filename', () => {
const timestampMillis = 1590174610000; // arbitrary timestamp in ms since epoch
const d = new Date(timestampMillis);
Expand Down
64 changes: 47 additions & 17 deletions snykTask/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,44 @@ async function showDirectoryListing(
}
}

export async function generateSnykCodeResultsWithoutIssues(
snykPath: string,
taskArgs: TaskArgs,
jsonReportOutputPath: string,
snykToken: string,
) {
const projectNameArg = taskArgs.getProjectNameParameter();

const options = getOptionsToExecuteSnykCLICommand(
taskArgs,
taskNameForAnalytics,
taskVersion,
snykToken,
);

const snykCodeTestToolRunner = tl
.tool(snykPath)
.arg('code')
.arg('test')
.arg('--json')
.argIf(
taskArgs.codeSeverityThreshold,
`--severity-threshold=${taskArgs.codeSeverityThreshold}`,
)
.argIf(taskArgs.ignoreUnknownCA, `--insecure`)
.argIf(taskArgs.organization, `--org=${taskArgs.organization}`)
.argIf(taskArgs.projectName, `--project-name=${projectNameArg}`)
.line(taskArgs.additionalArguments);

const snykCodeTestResult: tr.IExecSyncResult =
snykCodeTestToolRunner.execSync(options);
tl.writeFile(jsonReportOutputPath, snykCodeTestResult.stdout);

if (isDebugMode()) {
console.log(snykCodeTestResult);
}
}

async function runSnykTest(
snykPath: string,
taskArgs: TaskArgs,
Expand Down Expand Up @@ -199,28 +237,20 @@ async function runSnykTest(
}
const snykOutput: SnykOutput = { code: code, message: errorMsg };

// handle snyk code no-issues-found non-existent json by rerunning --json stdout to piped file
// handle inconsistency in snyk CLI for code test, when --json-file-output is specified
// and the test results in no issues found, no JSON is produced when it should still be
// just with an empty set of issues
if (
taskArgs.testType == TestType.CODE &&
!fs.existsSync(jsonReportOutputPath) &&
snykTestExitCode === CLI_EXIT_CODE_SUCCESS
) {
const echoToolRunner = tl.tool('echo');
const snykCodeTestToolRunner = tl
.tool(snykPath)
.arg('code')
.arg('test')
.arg('--json')
.argIf(
taskArgs.codeSeverityThreshold,
`--severity-threshold=${taskArgs.codeSeverityThreshold}`,
)
.argIf(taskArgs.ignoreUnknownCA, `--insecure`)
.argIf(taskArgs.organization, `--org=${taskArgs.organization}`)
.argIf(taskArgs.projectName, `--project-name=${projectNameArg}`)
.line(taskArgs.additionalArguments)
.pipeExecOutputToTool(echoToolRunner, jsonReportOutputPath);
await snykCodeTestToolRunner.exec(options);
await generateSnykCodeResultsWithoutIssues(
snykPath,
taskArgs,
jsonReportOutputPath,
snykToken,
);
}

removeRegexFromFile(
Expand Down
2 changes: 1 addition & 1 deletion snykTask/src/install/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export async function downloadExecutable(
const doDownload = () =>
new Promise<void>((resolve, reject) => {
https.get(executable.downloadUrl, (response) => {
response.on('end', () => resolve());
fileWriter.on('close', () => resolve());
response.on('error', (err) => {
console.error(
`Download of ${executable.filename} failed: ${err.message}`,
Expand Down
5 changes: 5 additions & 0 deletions snykTask/test/fixtures/golang-no-code-issues/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module app

go 1.12

require github.com/lib/pq v1.1.1
1 change: 1 addition & 0 deletions snykTask/test/fixtures/golang-no-code-issues/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
5 changes: 5 additions & 0 deletions snykTask/test/fixtures/golang-no-code-issues/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package main

func main() {
// nothing to see here
}

0 comments on commit fbf37b3

Please sign in to comment.