mirror of
https://github.com/selfxyz/self.git
synced 2026-04-27 03:01:15 -04:00
* add vercel config * update config * fix * make monorepo private for vercel * set node version * fix install * test * fix vercel webapp deploys * fix build command * better skip * prettier * format * fix deploy
190 lines
6.4 KiB
JavaScript
190 lines
6.4 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');
|
|
|
|
// Skip entirely on Vercel — all patches target React Native packages, none apply to web builds
|
|
if (process.env.VERCEL === '1') {
|
|
console.log('patch-package: skipping on Vercel (patches are React Native only)');
|
|
process.exit(0);
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
|
|
// Workspaces with isolated node_modules due to nmHoistingLimits: workspaces
|
|
// Most packages are in workspace node_modules, not root
|
|
const workspaceRoots = [
|
|
{ name: 'app', path: path.join(repositoryRootPath, 'app') },
|
|
{ name: 'contracts', path: path.join(repositoryRootPath, 'contracts') }
|
|
];
|
|
|
|
// Run patch-package with better error handling
|
|
try {
|
|
let anyPatchApplied = false;
|
|
let anyPatchFailed = false;
|
|
|
|
// Try root node_modules first (some packages may be hoisted here)
|
|
const rootNodeModules = path.join(repositoryRootPath, 'node_modules');
|
|
if (fs.existsSync(rootNodeModules)) {
|
|
const rootPatchRun = spawnSync('patch-package', ['--patch-dir', 'patches'], {
|
|
cwd: repositoryRootPath,
|
|
shell: true,
|
|
stdio: 'pipe', // Always capture output to check for real errors vs missing packages
|
|
timeout: 30000
|
|
});
|
|
const output = rootPatchRun.stdout?.toString() || '';
|
|
const stderrOutput = rootPatchRun.stderr?.toString() || '';
|
|
const hasRealError = (output.includes('**ERROR**') && !output.includes('which is not present at')) ||
|
|
(stderrOutput.length > 0 && rootPatchRun.status !== 0);
|
|
|
|
if (rootPatchRun.status === 0) {
|
|
if (!isCI) console.log('✓ Patches applied to root workspace');
|
|
anyPatchApplied = true;
|
|
} else if (hasRealError) {
|
|
console.error(`patch-package failed for root workspace`);
|
|
console.error(output);
|
|
if (stderrOutput) console.error(stderrOutput);
|
|
anyPatchFailed = true;
|
|
}
|
|
// If packages are just missing (not hoisted to root), that's expected - continue to workspace patches
|
|
}
|
|
|
|
// Apply patches to workspace node_modules (where most packages are with nmHoistingLimits)
|
|
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: 'pipe',
|
|
timeout: 30000
|
|
});
|
|
|
|
const output = workspacePatchRun.stdout?.toString() || '';
|
|
const stderrOutput = workspacePatchRun.stderr?.toString() || '';
|
|
const hasRealError = (output.includes('**ERROR**') && !output.includes('which is not present at')) ||
|
|
(stderrOutput.length > 0 && workspacePatchRun.status !== 0);
|
|
|
|
if (workspacePatchRun.status === 0) {
|
|
if (!isCI) console.log(`✓ Patches applied to ${workspace.name} workspace`);
|
|
anyPatchApplied = true;
|
|
} else if (hasRealError) {
|
|
console.error(`patch-package failed for ${workspace.name} workspace`);
|
|
console.error(output);
|
|
if (stderrOutput) console.error(stderrOutput);
|
|
anyPatchFailed = true;
|
|
}
|
|
}
|
|
|
|
if (anyPatchFailed && !isCI) {
|
|
console.error('Some patches failed to apply. Check if patch versions match installed package versions.');
|
|
process.exit(1);
|
|
}
|
|
if (anyPatchFailed && isCI) {
|
|
console.warn('⚠️ CI Warning: Some patches failed to apply. Review patch compatibility.');
|
|
}
|
|
|
|
if (anyPatchApplied) {
|
|
if (!isCI) console.log('✓ patch-package completed');
|
|
else console.log('patch-package completed');
|
|
} else {
|
|
if (!isCI) console.log('patch-package: no patches applied (packages may be in different locations)');
|
|
else console.log('patch-package: no patches applied');
|
|
}
|
|
} 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);
|