Files
LobsterAI/scripts/run-build-openclaw-runtime.cjs
btc69m979y-dotcomandClaude Opus 4.6 6bb25e2ef2 feat: pin OpenClaw dependency to versioned releases with auto-fetch and build cache
- Add `openclaw.version` and `openclaw.repo` config in package.json
- Add `ensure-openclaw-version.cjs` to auto-clone or checkout the pinned tag
- Add build cache in `build-openclaw-runtime.sh` — skip rebuild when version matches
- Enhanced `runtime-build-info.json` with openclawVersion and openclawCommit
- Fix Windows: prefer Git Bash over WSL bash (WindowsApps\bash.exe)
- Fix Windows: normalize PATH env for bash, use relative script path
- Fix Windows: add `shell: true` for npm.cmd in openclaw-runtime-host.cjs
- Add `.gitattributes` to enforce LF line endings for .sh files
- Update README.md and README_zh.md with OpenClaw dev workflow and version management docs

Co-Authored-By: Claude Opus 4.6 <[email protected]>
2026-03-06 16:35:07 +08:00

113 lines
3.8 KiB
JavaScript

'use strict';
const { spawnSync } = require('child_process');
const fs = require('fs');
const path = require('path');
function commandExists(command) {
const checker = process.platform === 'win32' ? 'where' : 'which';
const result = spawnSync(checker, [command], { stdio: 'ignore' });
return result.status === 0;
}
function resolveBashExecutable(rootDir) {
if (process.platform !== 'win32') {
return commandExists('bash') ? 'bash' : null;
}
// On Windows, we must use Git Bash (MSYS2), NOT WSL's bash.
// WSL bash (WindowsApps\bash.exe) runs in a separate Linux environment and
// cannot access Windows-installed node, npm, pnpm, etc.
// 1. Check all bash locations, prefer Git Bash over WSL bash.
try {
const result = spawnSync('where', ['bash'], {
encoding: 'utf-8',
stdio: ['ignore', 'pipe', 'ignore'],
});
if (result.status === 0 && result.stdout) {
const paths = result.stdout.trim().split(/\r?\n/).map(p => p.trim()).filter(Boolean);
const gitBash = paths.find(p => !p.toLowerCase().includes('windowsapps'));
if (gitBash) return gitBash;
}
} catch {}
// 2. Derive bash path from git installation.
try {
const gitResult = spawnSync('where', ['git'], {
encoding: 'utf-8',
stdio: ['ignore', 'pipe', 'ignore'],
});
if (gitResult.status === 0 && gitResult.stdout) {
const gitPath = gitResult.stdout.trim().split(/\r?\n/)[0].trim();
const gitRoot = path.resolve(path.dirname(gitPath), '..');
const gitBashCandidates = [
path.join(gitRoot, 'bin', 'bash.exe'),
path.join(gitRoot, 'usr', 'bin', 'bash.exe'),
];
for (const candidate of gitBashCandidates) {
if (fs.existsSync(candidate)) return candidate;
}
}
} catch {}
// 3. Bundled mingit bash.
const candidates = [
path.join(rootDir, 'resources', 'mingit', 'bin', 'bash.exe'),
path.join(rootDir, 'resources', 'mingit', 'usr', 'bin', 'bash.exe'),
];
for (const candidate of candidates) {
if (fs.existsSync(candidate)) {
return candidate;
}
}
return null;
}
const targetId = (process.argv[2] || '').trim();
if (!targetId) {
console.error('[run-build-openclaw-runtime] Missing target id (example: mac-arm64, win-x64, linux-x64).');
process.exit(1);
}
const rootDir = path.resolve(__dirname, '..');
const bashExecutable = resolveBashExecutable(rootDir);
if (!bashExecutable) {
console.error('[run-build-openclaw-runtime] bash is required but not found.');
if (process.platform === 'win32') {
console.error('[run-build-openclaw-runtime] Install Git Bash or run `npm run setup:mingit` first.');
}
process.exit(1);
}
// On Windows, normalise the environment for bash:
// 1. Bash expects "PATH" (uppercase) but Windows may use "Path" — merge all
// case-variants into a single uppercase "PATH".
// 2. Prepend the directory containing the current node binary so that node,
// npm, pnpm, etc. are findable inside the bash script even when spawned
// through deeply-nested npm/cmd.exe process chains.
const env = { ...process.env };
if (process.platform === 'win32') {
const nodeDir = path.dirname(process.execPath);
const pathEntries = Object.entries(env).filter(([k]) => k.toUpperCase() === 'PATH');
const pathValue = pathEntries.map(([, v]) => v).join(path.delimiter);
for (const [k] of pathEntries) delete env[k];
env.PATH = `${nodeDir}${path.delimiter}${pathValue}`;
}
// Use a relative path so bash never sees Windows drive-letter paths like
// "D:/..." which can fail when invoked through nested npm/cmd.exe chains.
const scriptPath = 'scripts/build-openclaw-runtime.sh';
const result = spawnSync(bashExecutable, [scriptPath, targetId], {
cwd: rootDir,
env,
stdio: 'inherit',
});
if (typeof result.status === 'number') {
process.exit(result.status);
}
process.exit(1);