mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-22 13:38:07 +00:00
fix(docker): seed prune store from lockfile
This commit is contained in:
@@ -138,7 +138,7 @@ ARG OPENCLAW_BUNDLED_PLUGIN_DIR
|
||||
# BuildKit cache mounts are not part of cached layers; seed tarballs for the
|
||||
# installed prod graph in the same step that runs offline prune.
|
||||
RUN --mount=type=cache,id=openclaw-pnpm-store,target=/root/.local/share/pnpm/store,sharing=locked \
|
||||
pnpm list --prod --depth Infinity --json | node scripts/list-prod-store-packages.mjs | xargs -r pnpm store add && \
|
||||
node scripts/list-prod-store-packages.mjs | xargs -r pnpm store add && \
|
||||
CI=true pnpm prune --prod \
|
||||
--config.offline=true \
|
||||
--config.supportedArchitectures.os=linux \
|
||||
|
||||
@@ -3,8 +3,6 @@ import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { parse } from "yaml";
|
||||
|
||||
const parsed = JSON.parse(fs.readFileSync(0, "utf8"));
|
||||
const roots = Array.isArray(parsed) ? parsed : [parsed];
|
||||
const specs = new Set();
|
||||
const target = {
|
||||
cpu: process.arch,
|
||||
@@ -24,6 +22,12 @@ function packageSpec(name, version) {
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
if (normalizedVersion.startsWith("npm:")) {
|
||||
return normalizedVersion.slice("npm:".length);
|
||||
}
|
||||
if (normalizedVersion.startsWith("@")) {
|
||||
return normalizedVersion;
|
||||
}
|
||||
return `${name}@${normalizedVersion}`;
|
||||
}
|
||||
|
||||
@@ -85,6 +89,15 @@ function addSpec(lockfile, spec) {
|
||||
}
|
||||
}
|
||||
|
||||
function parseListRoots() {
|
||||
const input = fs.readFileSync(0, "utf8").trim();
|
||||
if (!input) {
|
||||
return [];
|
||||
}
|
||||
const parsed = JSON.parse(input);
|
||||
return Array.isArray(parsed) ? parsed : [parsed];
|
||||
}
|
||||
|
||||
function visitListNode(lockfile, node) {
|
||||
for (const dep of Object.values(node.dependencies ?? {})) {
|
||||
const name = dep.from || dep.name;
|
||||
@@ -96,6 +109,16 @@ function visitListNode(lockfile, node) {
|
||||
}
|
||||
}
|
||||
|
||||
function addImporterRoots(lockfile) {
|
||||
for (const importer of Object.values(lockfile?.importers ?? {})) {
|
||||
for (const deps of [importer.dependencies, importer.optionalDependencies]) {
|
||||
for (const [name, dep] of Object.entries(deps ?? {})) {
|
||||
addSpec(lockfile, packageSpec(name, dep?.version));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function readLockfile() {
|
||||
const lockfilePath = path.join(process.cwd(), "pnpm-lock.yaml");
|
||||
if (!fs.existsSync(lockfilePath)) {
|
||||
@@ -145,9 +168,10 @@ function addSnapshotClosure(lockfile) {
|
||||
}
|
||||
|
||||
const lockfile = readLockfile();
|
||||
for (const root of roots) {
|
||||
for (const root of parseListRoots()) {
|
||||
visitListNode(lockfile, root);
|
||||
}
|
||||
addImporterRoots(lockfile);
|
||||
addSnapshotClosure(lockfile);
|
||||
|
||||
process.stdout.write([...specs].toSorted((a, b) => a.localeCompare(b)).join("\n"));
|
||||
|
||||
@@ -101,7 +101,7 @@ describe("Dockerfile", () => {
|
||||
const dockerfile = await readFile(dockerfilePath, "utf8");
|
||||
const installIndex = dockerfile.indexOf("pnpm install --frozen-lockfile \\");
|
||||
const storeSeedIndex = dockerfile.indexOf(
|
||||
"pnpm list --prod --depth Infinity --json | node scripts/list-prod-store-packages.mjs | xargs -r pnpm store add",
|
||||
"node scripts/list-prod-store-packages.mjs | xargs -r pnpm store add",
|
||||
);
|
||||
const pruneIndex = dockerfile.indexOf("CI=true pnpm prune --prod \\");
|
||||
|
||||
|
||||
@@ -16,6 +16,14 @@ function runListProdStorePackages(input: unknown, cwd = process.cwd()) {
|
||||
});
|
||||
}
|
||||
|
||||
function runListProdStorePackagesRaw(input: string, cwd = process.cwd()) {
|
||||
return spawnSync(process.execPath, [scriptPath], {
|
||||
cwd,
|
||||
encoding: "utf8",
|
||||
input,
|
||||
});
|
||||
}
|
||||
|
||||
describe("list-prod-store-packages", () => {
|
||||
afterEach(() => {
|
||||
cleanupTempDirs(tempDirs);
|
||||
@@ -101,6 +109,64 @@ describe("list-prod-store-packages", () => {
|
||||
expect(result.stdout).toBe("source-map-support@0.5.21\nsource-map@0.6.1");
|
||||
});
|
||||
|
||||
it("adds production importer dependency closures without pnpm list input", () => {
|
||||
const cwd = makeTempRepoRoot(tempDirs, "openclaw-prod-store-packages-");
|
||||
writeFileSync(
|
||||
join(cwd, "pnpm-lock.yaml"),
|
||||
[
|
||||
"lockfileVersion: '10.0'",
|
||||
"",
|
||||
"importers:",
|
||||
" .:",
|
||||
" dependencies:",
|
||||
" '@homebridge/ciao':",
|
||||
" specifier: 1.3.9",
|
||||
" version: 1.3.9",
|
||||
" fetch-blob:",
|
||||
" specifier: 3.2.0",
|
||||
" version: 3.2.0",
|
||||
"",
|
||||
"packages:",
|
||||
" '@homebridge/ciao@1.3.9':",
|
||||
" resolution: {integrity: sha512-test}",
|
||||
" source-map-support@0.5.21:",
|
||||
" resolution: {integrity: sha512-test}",
|
||||
" source-map@0.6.1:",
|
||||
" resolution: {integrity: sha512-test}",
|
||||
" fetch-blob@3.2.0:",
|
||||
" resolution: {integrity: sha512-test}",
|
||||
" '@nolyfill/domexception@1.0.28':",
|
||||
" resolution: {integrity: sha512-test}",
|
||||
"",
|
||||
"snapshots:",
|
||||
" '@homebridge/ciao@1.3.9':",
|
||||
" dependencies:",
|
||||
" source-map-support: 0.5.21",
|
||||
" source-map-support@0.5.21:",
|
||||
" dependencies:",
|
||||
" source-map: 0.6.1",
|
||||
" source-map@0.6.1: {}",
|
||||
" fetch-blob@3.2.0:",
|
||||
" dependencies:",
|
||||
" node-domexception: '@nolyfill/domexception@1.0.28'",
|
||||
" '@nolyfill/domexception@1.0.28': {}",
|
||||
"",
|
||||
].join("\n"),
|
||||
);
|
||||
const result = runListProdStorePackagesRaw("", cwd);
|
||||
|
||||
expect(result.status).toBe(0);
|
||||
expect(result.stdout.split("\n")).toEqual(
|
||||
[
|
||||
"@homebridge/ciao@1.3.9",
|
||||
"fetch-blob@3.2.0",
|
||||
"@nolyfill/domexception@1.0.28",
|
||||
"source-map-support@0.5.21",
|
||||
"source-map@0.6.1",
|
||||
].toSorted((a, b) => a.localeCompare(b)),
|
||||
);
|
||||
});
|
||||
|
||||
it("adds target optional dependencies from peer-resolved lockfile snapshots", () => {
|
||||
const cwd = makeTempRepoRoot(tempDirs, "openclaw-prod-store-packages-");
|
||||
const platformPackages = [
|
||||
|
||||
Reference in New Issue
Block a user