Skip to content

Commit b757490

Browse files
authored
chore(ci): fix snyk test hanging COMPASS-7947 (#5820)
* chore(ci): fix snyk test hanging COMPASS-7947 * fix env var name * fix check * use already available make-fetch-happen
1 parent 72762a8 commit b757490

File tree

3 files changed

+47
-196
lines changed

3 files changed

+47
-196
lines changed

package-lock.json

Lines changed: 0 additions & 112 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
"@mongodb-js/monorepo-tools": "^1.1.1",
4242
"commander": "^11.0.0",
4343
"electron": "^29.4.0",
44-
"glob": "^10.2.5",
4544
"jsdom": "^21.1.0",
4645
"make-fetch-happen": "^8.0.14",
4746
"pacote": "^11.3.5",

scripts/snyk-test.js

Lines changed: 47 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,70 @@
11
'use strict';
2-
const childProcess = require('child_process');
3-
const path = require('path');
42
const { promises: fs } = require('fs');
5-
const os = require('os');
6-
const { glob } = require('glob');
7-
const { promisify } = require('util');
8-
const execFile = promisify(childProcess.execFile);
3+
const path = require('path');
4+
const fetch = require('make-fetch-happen');
5+
6+
const MAKE_FETCH_HAPPEN_OPTIONS = {
7+
timeout: 10000,
8+
retry: {
9+
retries: 3,
10+
factor: 1,
11+
minTimeout: 1000,
12+
maxTimeout: 3000,
13+
randomize: true,
14+
},
15+
};
16+
17+
async function snykTest(dependency) {
18+
const { name, version } = dependency;
19+
20+
process.stdout.write(`Testing ${name}@${version} ... `);
21+
22+
const response = await fetch(
23+
`https://api.snyk.io/v1/test/npm/${encodeURIComponent(name)}/${version}`,
24+
{
25+
...MAKE_FETCH_HAPPEN_OPTIONS,
26+
headers: {
27+
Authorization: `token ${process.env.SNYK_TOKEN}`,
28+
},
29+
}
30+
);
931

10-
async function fileExists(filePath) {
11-
try {
12-
await fs.access(filePath);
13-
return true;
14-
} catch {
15-
return false;
32+
if (!response.ok) {
33+
throw new Error(`HTTP error! status: ${response.status}`);
1634
}
17-
}
1835

19-
async function snykTest(cwd) {
20-
const tmpPath = path.join(os.tmpdir(), 'tempfile-' + Date.now());
36+
const vulnerabilities = (await response.json()).issues?.vulnerabilities ?? [];
2137

22-
let execErr;
23-
24-
try {
25-
if (!(await fileExists(path.join(cwd, `package.json`)))) {
26-
return;
27-
}
28-
29-
console.info(`testing ${cwd} ...`);
30-
await fs.mkdir(path.join(cwd, `node_modules`), { recursive: true });
31-
32-
try {
33-
await execFile(
34-
'npx',
35-
[
36-
'snyk@latest',
37-
'test',
38-
'--all-projects',
39-
'--severity-threshold=low',
40-
'--dev',
41-
`--json-file-output=${tmpPath}`,
42-
],
43-
{
44-
cwd,
45-
maxBuffer: 50 /* MB */ * 1024 * 1024, // default is 1 MB
46-
}
47-
);
48-
} catch (err) {
49-
execErr = err;
50-
}
38+
process.stdout.write(`Done\n`);
5139

52-
const res = JSON.parse(await fs.readFile(tmpPath));
53-
console.info(`testing ${cwd} done.`);
54-
return res;
55-
} catch (err) {
56-
console.error(`Snyk failed to create a json report for ${cwd}:`, execErr);
57-
throw new Error(`Testing ${cwd} failed.`);
58-
} finally {
59-
try {
60-
await fs.rm(tmpPath);
61-
} catch (error) {
62-
//
63-
}
64-
}
40+
return vulnerabilities.map((v) => {
41+
// for some reason the api doesn't add these properties unlike `snyk test`
42+
return { ...v, name: v.package, fixedIn: v.upgradePath ?? [] };
43+
});
6544
}
6645

6746
async function main() {
68-
const rootPath = path.resolve(__dirname, '..');
47+
if (!process.env.SNYK_TOKEN) {
48+
throw new Error('process.env.SNYK_TOKEN is missing.');
49+
}
6950

70-
const { workspaces } = JSON.parse(
71-
await fs.readFile(path.join(rootPath, 'package.json'))
72-
);
51+
const rootPath = path.resolve(__dirname, '..');
7352

74-
const packages = (await Promise.all(workspaces.map((w) => glob(w)))).flat();
53+
const dependenciesFile = path.join(rootPath, '.sbom', 'dependencies.json');
54+
const dependencies = JSON.parse(await fs.readFile(dependenciesFile, 'utf-8'));
7555

7656
const results = [];
7757

78-
results.push(await snykTest(rootPath));
79-
80-
for (const location of packages) {
81-
const result = await snykTest(location);
82-
if (result) {
83-
results.push(result);
58+
for (const dependency of dependencies) {
59+
const vulnerabilities = await snykTest(dependency);
60+
if (vulnerabilities && vulnerabilities.length) {
61+
results.push({ vulnerabilities });
8462
}
8563
}
8664

87-
await fs.mkdir(path.join(rootPath, `.sbom`), { recursive: true });
88-
8965
await fs.writeFile(
9066
path.join(rootPath, `.sbom/snyk-test-result.json`),
91-
JSON.stringify(results.flat(), null, 2)
92-
);
93-
94-
await execFile(
95-
'npx',
96-
[
97-
'snyk-to-html',
98-
'-i',
99-
path.join(rootPath, '.sbom/snyk-test-result.json'),
100-
'-o',
101-
path.join(rootPath, `.sbom/snyk-test-result.html`),
102-
],
103-
{ cwd: rootPath }
67+
JSON.stringify(results, null, 2)
10468
);
10569
}
10670

0 commit comments

Comments
 (0)