Files
self/scripts/run-patch-package.cjs
Justin Hernandez 1c3b054f3b chore: address failing test_circuits pipeline (#1465)
* test bump for contracts

* Patch ethereum-cryptography assertions (#1466)

* check patches

* Apply patches in workspace node_modules (#1467)

* comment out init method

* pin packages and finally fix pipelines?

* address coderabbit feedback

* downgrading due to cve
2025-12-04 23:20:55 -08:00

147 lines
4.6 KiB
JavaScript

#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const { spawnSync } = require('child_process');
const repositoryRootPath = path.resolve(__dirname, '..');
const patchesDirectoryPath = path.join(repositoryRootPath, 'patches');
// Detect CI environment
const isCI = process.env.CI === 'true' ||
process.env.GITHUB_ACTIONS === 'true' ||
process.env.CIRCLECI === 'true' ||
process.env.TRAVIS === 'true' ||
process.env.BUILDKITE === 'true' ||
process.env.GITLAB_CI === 'true' ||
process.env.JENKINS_URL !== undefined;
function directoryContainsPatchFiles(directoryPath) {
try {
if (!fs.existsSync(directoryPath)) return false;
const entries = fs.readdirSync(directoryPath);
for (const entryName of entries) {
const absoluteEntryPath = path.join(directoryPath, entryName);
const entryStats = fs.statSync(absoluteEntryPath);
if (entryStats.isDirectory()) {
if (directoryContainsPatchFiles(absoluteEntryPath)) return true;
} else if (entryName.endsWith('.patch')) {
return true;
}
}
return false;
} catch {
return false;
}
}
function isExecutableAvailableOnPath(executableName) {
// Try multiple methods to check if executable is available
const commands = process.platform === 'win32'
? ['where', 'where.exe']
: ['command -v', 'which', '/usr/bin/which'];
for (const command of commands) {
try {
const whichResult = spawnSync(command, [executableName], {
shell: true,
stdio: 'ignore',
timeout: 5000 // 5 second timeout
});
if (whichResult.status === 0) {
return true;
}
} catch (error) {
// Continue to next command
continue;
}
}
return false;
}
// Early exit conditions
if (!fs.existsSync(patchesDirectoryPath)) {
if (isCI) {
console.log('patch-package: patches directory not found, skipping (CI mode)');
} else {
console.log('patch-package: patches directory not found, skipping');
}
process.exit(0);
}
if (!directoryContainsPatchFiles(patchesDirectoryPath)) {
if (isCI) {
console.log('patch-package: no patches found, skipping (CI mode)');
} else {
console.log('patch-package: no patches found, skipping');
}
process.exit(0);
}
// Check if patch-package is available
if (!isExecutableAvailableOnPath('patch-package')) {
if (isCI) {
console.log('patch-package not installed, skipping (CI mode)');
} else {
console.log('patch-package not installed, skipping');
}
process.exit(0);
}
// Run patch-package with better error handling
try {
const rootPatchRun = spawnSync('patch-package', ['--patch-dir', 'patches'], {
cwd: repositoryRootPath,
shell: true,
stdio: isCI ? 'pipe' : 'inherit',
timeout: 30000
});
if (rootPatchRun.status === 0) {
if (!isCI) console.log('✓ Patches applied to root workspace');
} else {
const errorOutput = rootPatchRun.stderr?.toString() || rootPatchRun.stdout?.toString() || '';
console.error(`patch-package failed for root workspace (exit code ${rootPatchRun.status})`);
if (errorOutput) console.error(errorOutput);
if (!isCI) process.exit(1);
}
// Also patch app/node_modules if it exists
// Workspaces with isolated node_modules due to limited hoisting
const workspaceRoots = [
{ name: 'app', path: path.join(repositoryRootPath, 'app') },
{ name: 'contracts', path: path.join(repositoryRootPath, 'contracts') }
];
for (const workspace of workspaceRoots) {
const workspaceNodeModules = path.join(workspace.path, 'node_modules');
if (!fs.existsSync(workspaceNodeModules)) continue;
const workspacePatchRun = spawnSync('patch-package', ['--patch-dir', '../patches'], {
cwd: workspace.path,
shell: true,
stdio: isCI ? 'pipe' : 'inherit',
timeout: 30000
});
if (workspacePatchRun.status === 0) {
if (!isCI) console.log(`✓ Patches applied to ${workspace.name} workspace`);
} else {
const errorOutput = workspacePatchRun.stderr?.toString() || workspacePatchRun.stdout?.toString() || '';
console.error(`patch-package failed for ${workspace.name} workspace (exit code ${workspacePatchRun.status})`);
if (errorOutput) console.error(errorOutput);
if (!isCI) process.exit(1);
}
}
} catch (error) {
if (isCI) {
console.log('patch-package: error during execution (CI mode):', error.message);
console.log('Continuing build despite patch errors...');
process.exit(0);
} else {
console.error('patch-package error:', error.message);
process.exit(1);
}
}
process.exit(0);