Skip to content

Commit ee29149

Browse files
fix: snyk will now scan vscode project
Earlier snyk was never scanning the vscode project because of the combination of project auto-detection and the presence of .vscode-test folder which contains several directories with package.json files. This commit disables the auto-detection so that snyk run tests on the current project. Additionally the current project was having a problem with a package declaring optional dependencies. These optional dependencies were platform specific so for any platform, all the optional dependencies will never be installed, only the ones that are platform compatible. Snyk requires what is declared in package-lock.json to be also present in node_modules folder which is why it would've failed. In the same commit, we added a pre and post test hook to remove the identified problematic optional dependencies from package-lock file before running the test and then restore it when the test is finished.
1 parent d0a1a18 commit ee29149

File tree

1 file changed

+89
-20
lines changed

1 file changed

+89
-20
lines changed

scripts/snyk-test.js

Lines changed: 89 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,67 @@ const { glob } = require('glob');
66
const { promisify } = require('util');
77
const execFile = promisify(childProcess.execFile);
88

9+
const PACKAGE_LOCK_PATH = path.join(__dirname, '..', 'package-lock.json');
10+
11+
/**
12+
* "node_modules/@vscode/vsce-sign" package which is a dev dependency used for
13+
* publishing extension declares platform specific optionalDependencies, namely
14+
* the following:
15+
* - "@vscode/vsce-sign-alpine-arm64"
16+
* - "@vscode/vsce-sign-alpine-x64"
17+
* - "@vscode/vsce-sign-darwin-arm64"
18+
* - "@vscode/vsce-sign-darwin-x64"
19+
* - "@vscode/vsce-sign-linux-arm"
20+
* - "@vscode/vsce-sign-linux-arm64"
21+
* - "@vscode/vsce-sign-linux-x64"
22+
* - "@vscode/vsce-sign-win32-arm64"
23+
* - "@vscode/vsce-sign-win32-x64"
24+
*
25+
* Snyk requires what is declared in package-lock.json to be also present in
26+
* installed node_modules but this will never happen because for any platform,
27+
* other platform specific deps will always be missing which means Snyk will
28+
* always fail in this case.
29+
*
30+
* Because we always install with `npm ci --omit=optional`, with this method we
31+
* try to remove these identified problematic optionalDependencies before
32+
* running the Snyk tests and once the tests are finished, we restore the
33+
* original state back.
34+
*/
35+
async function removeProblematicOptionalDepsFromPackageLock() {
36+
const TEMP_PACKAGE_LOCK_PATH = path.join(
37+
__dirname,
38+
'..',
39+
'original-package-lock.json',
40+
);
41+
42+
const packageLockContent = JSON.parse(
43+
await fs.readFile(PACKAGE_LOCK_PATH, 'utf-8'),
44+
);
45+
46+
if (
47+
!packageLockContent.packages?.['node_modules/@vscode/vsce-sign']?.[
48+
'optionalDependencies'
49+
]
50+
) {
51+
console.info('No problematic optional dependencies to fix');
52+
return;
53+
}
54+
55+
packageLockContent.packages['node_modules/@vscode/vsce-sign'][
56+
'optionalDependencies'
57+
] = {};
58+
59+
await fs.rename(PACKAGE_LOCK_PATH, TEMP_PACKAGE_LOCK_PATH);
60+
await fs.writeFile(
61+
PACKAGE_LOCK_PATH,
62+
JSON.stringify(packageLockContent, null, 2),
63+
);
64+
65+
return async function restoreOriginalPackageLock() {
66+
return await fs.rename(TEMP_PACKAGE_LOCK_PATH, PACKAGE_LOCK_PATH);
67+
};
68+
}
69+
970
async function snykTest(cwd) {
1071
const tmpPath = path.join(os.tmpdir(), 'tempfile-' + Date.now());
1172

@@ -17,9 +78,8 @@ async function snykTest(cwd) {
1778
await execFile(
1879
'npx',
1980
[
20-
'snyk',
81+
'snyk@latest',
2182
'test',
22-
'--all-projects',
2383
'--severity-threshold=low',
2484
'--dev',
2585
`--json-file-output=${tmpPath}`,
@@ -45,26 +105,35 @@ async function snykTest(cwd) {
45105
}
46106

47107
async function main() {
48-
const rootPath = path.resolve(__dirname, '..');
49-
await fs.mkdir(path.join(rootPath, `.sbom`), { recursive: true });
50-
const results = await snykTest(rootPath);
108+
let revertPackageLockChanges;
109+
try {
110+
const rootPath = path.resolve(__dirname, '..');
111+
await fs.mkdir(path.join(rootPath, `.sbom`), { recursive: true });
112+
revertPackageLockChanges =
113+
await removeProblematicOptionalDepsFromPackageLock();
114+
const results = await snykTest(rootPath);
51115

52-
await fs.writeFile(
53-
path.join(rootPath, `.sbom/snyk-test-result.json`),
54-
JSON.stringify(results, null, 2),
55-
);
116+
await fs.writeFile(
117+
path.join(rootPath, `.sbom/snyk-test-result.json`),
118+
JSON.stringify(results, null, 2),
119+
);
56120

57-
await execFile(
58-
'npx',
59-
[
60-
'snyk-to-html',
61-
'-i',
62-
path.join(rootPath, '.sbom/snyk-test-result.json'),
63-
'-o',
64-
path.join(rootPath, `.sbom/snyk-test-result.html`),
65-
],
66-
{ cwd: rootPath },
67-
);
121+
await execFile(
122+
'npx',
123+
[
124+
'snyk-to-html',
125+
'-i',
126+
path.join(rootPath, '.sbom/snyk-test-result.json'),
127+
'-o',
128+
path.join(rootPath, `.sbom/snyk-test-result.html`),
129+
],
130+
{ cwd: rootPath },
131+
);
132+
} finally {
133+
if (revertPackageLockChanges) {
134+
await revertPackageLockChanges();
135+
}
136+
}
68137
}
69138

70139
main();

0 commit comments

Comments
 (0)