fix: remove shell usage from plugin check (#1367)

* fix: remove shell usage from plugin check

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: harden plugin symlink scan

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Aaron Powell
2026-04-10 14:24:59 +10:00
committed by GitHub
parent cfe4143cdd
commit 7df3657076

View File

@@ -21,13 +21,50 @@ jobs:
uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0 uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7.1.0
with: with:
script: | script: |
const { execSync } = require('child_process');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const pluginsDir = 'plugins'; const pluginsDir = 'plugins';
const errors = []; const errors = [];
function findSymlinks(rootDir) {
const symlinks = [];
const dirsToScan = [rootDir];
while (dirsToScan.length > 0) {
const currentDir = dirsToScan.pop();
let entries;
try {
entries = fs.readdirSync(currentDir, { withFileTypes: true });
} catch (error) {
throw new Error(`Failed to read directory "${currentDir}": ${error.message}`);
}
for (const entry of entries) {
const entryPath = path.join(currentDir, entry.name);
let stat;
try {
stat = fs.lstatSync(entryPath);
} catch (error) {
throw new Error(`Failed to inspect "${entryPath}": ${error.message}`);
}
if (stat.isSymbolicLink()) {
symlinks.push(entryPath);
continue;
}
if (stat.isDirectory()) {
dirsToScan.push(entryPath);
}
}
}
return symlinks;
}
if (!fs.existsSync(pluginsDir)) { if (!fs.existsSync(pluginsDir)) {
console.log('No plugins directory found'); console.log('No plugins directory found');
return; return;
@@ -63,14 +100,15 @@ jobs:
} }
} }
// Check for symlinks anywhere in the plugin directory // Check for symlinks anywhere in the plugin directory without invoking a shell
try { try {
const allFiles = execSync(`find "${pluginPath}" -type l`, { encoding: 'utf-8' }).trim(); const symlinkPaths = findSymlinks(pluginPath);
if (allFiles) { if (symlinkPaths.length > 0) {
errors.push(`${pluginPath} contains symlinks:\n${allFiles}`); const formattedPaths = symlinkPaths.map(filePath => `\`${filePath}\``).join(', ');
errors.push(`${pluginPath} contains symlinks: ${formattedPaths}`);
} }
} catch (e) { } catch (error) {
// find returns non-zero if no matches, ignore errors.push(`Failed to inspect ${pluginPath} for symlinks: ${error.message}`);
} }
} }