Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .buildchain/kfd-1/libnode-contract-world.witness.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
"contractWorld": {
"id": "libnode-release-contract",
"schemaId": "https://kfd.libkungfu.dev/schemas/kfd-1/contract-world.schema.json",
"digest": "sha256:e07b53986f76d8a3af0ec58b6c7abbc2b6a94261e2da0004280f0a143cf0c3a0"
"digest": "sha256:89209c832af5dffee0d73e33b0d2b4c68cd0b2693141ef6472e31e673ce5790c"
},
"standardContract": {
"id": "libnode-release-contract",
"path": "libnode.release.json",
"sha256": "e07b53986f76d8a3af0ec58b6c7abbc2b6a94261e2da0004280f0a143cf0c3a0"
"sha256": "89209c832af5dffee0d73e33b0d2b4c68cd0b2693141ef6472e31e673ce5790c"
},
"selfHostingBoundary": {
"mode": "self-hosted-standard-contract",
Expand All @@ -33,25 +33,25 @@
{
"name": "package-manifest",
"sourcePath": "package.json",
"sourceSha256": "9092f881f572b36c7bddda388a4bcd6c11b366e56405616715fb58bafe7173bf",
"sourceSha256": "a20cf95aed25d87a6cf960e74a2ec23d0411ffdd958c9321ece0ec8249f82979",
"artifactPath": "package.json",
"expectedSha256": "9092f881f572b36c7bddda388a4bcd6c11b366e56405616715fb58bafe7173bf",
"expectedSha256": "a20cf95aed25d87a6cf960e74a2ec23d0411ffdd958c9321ece0ec8249f82979",
"byteForByte": true
},
{
"name": "release-manifest",
"sourcePath": "libnode.release.json",
"sourceSha256": "e07b53986f76d8a3af0ec58b6c7abbc2b6a94261e2da0004280f0a143cf0c3a0",
"sourceSha256": "89209c832af5dffee0d73e33b0d2b4c68cd0b2693141ef6472e31e673ce5790c",
"artifactPath": "libnode.release.json",
"expectedSha256": "e07b53986f76d8a3af0ec58b6c7abbc2b6a94261e2da0004280f0a143cf0c3a0",
"expectedSha256": "89209c832af5dffee0d73e33b0d2b4c68cd0b2693141ef6472e31e673ce5790c",
"byteForByte": true
},
{
"name": "buildchain-config",
"sourcePath": "buildchain.toml",
"sourceSha256": "1ccbc2dee94a30dff10b7596125340a985e8150febe74e7efe0b67f11299e972",
"sourceSha256": "1ed7e2677a7b551264f86a40c6985adeebca590a942e358a57844b5d05a2aa3d",
"artifactPath": "buildchain.toml",
"expectedSha256": "1ccbc2dee94a30dff10b7596125340a985e8150febe74e7efe0b67f11299e972",
"expectedSha256": "1ed7e2677a7b551264f86a40c6985adeebca590a942e358a57844b5d05a2aa3d",
"byteForByte": true
},
{
Expand Down Expand Up @@ -97,9 +97,9 @@
{
"name": "kfd3-prebuild-witness",
"sourcePath": ".buildchain/kfd-3/collaboration-interface.prebuild.json",
"sourceSha256": "b6fe7ab725271e6a478550338b2c749fd848ca48b0536ab3ebbd10728a382812",
"sourceSha256": "a190401a0e1536b9d0f01e4168d30f7c8dae1a3bf6fed03c743a64e659d62262",
"artifactPath": ".buildchain/kfd-3/collaboration-interface.prebuild.json",
"expectedSha256": "b6fe7ab725271e6a478550338b2c749fd848ca48b0536ab3ebbd10728a382812",
"expectedSha256": "a190401a0e1536b9d0f01e4168d30f7c8dae1a3bf6fed03c743a64e659d62262",
"byteForByte": true
}
]
Expand Down
2 changes: 1 addition & 1 deletion .buildchain/kfd-3/collaboration-interface.prebuild.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"sourceRegistry": {
"id": "libnode-release-contract",
"path": "libnode.release.json",
"version": "22.22.3-kf.3-alpha.14"
"version": "22.22.3-kf.3-alpha.15"
},
"collaborationInterfaceDigest": "sha256:da72832c4fee28021f90381b86ed94ccf6d8bddcb23b80419d256e5a9e4bb653",
"collaborationInterface": {
Expand Down
164 changes: 164 additions & 0 deletions .gyp/libnode-kfd-witnesses.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
const crypto = require('crypto');
const childProcess = require('child_process');
const fs = require('fs');
const path = require('path');

const repoRoot = path.resolve(__dirname, '..');
let useGitBlobContent = false;

const paths = {
packageJson: 'package.json',
release: 'libnode.release.json',
buildchain: 'buildchain.toml',
platformPackage: '.gyp/node-platform-package.js',
releaseVerify: '.gyp/libnode-release-verify.js',
kfd3ArtifactVerify: '.gyp/libnode-kfd3-artifact-verify.js',
releaseWorkflow: '.github/workflows/release-new-version.yml',
kfd3Interface: '.buildchain/kfd-3/collaboration-interface.json',
kfd3Prebuild: '.buildchain/kfd-3/collaboration-interface.prebuild.json',
kfd1Witness: '.buildchain/kfd-1/libnode-contract-world.witness.json',
};

function readJson(relativePath) {
return JSON.parse(fileText(relativePath));
}

function gitBlob(relativePath) {
const result = childProcess.spawnSync('git', ['show', `HEAD:${relativePath}`], {
cwd: repoRoot,
stdio: ['ignore', 'pipe', 'pipe'],
windowsHide: true,
});
if (result.status !== 0) {
const stderr = result.stderr.toString('utf8').trim();
throw new Error(`git show HEAD:${relativePath} failed${stderr ? `: ${stderr}` : ''}`);
}
return result.stdout;
}

function fileBytes(relativePath) {
return useGitBlobContent ? gitBlob(relativePath) : fs.readFileSync(path.join(repoRoot, relativePath));
}

function fileText(relativePath) {
return fileBytes(relativePath).toString('utf8');
}

function sha256File(relativePath) {
return crypto.createHash('sha256').update(fileBytes(relativePath)).digest('hex');
}

function jsonText(value) {
return `${JSON.stringify(value, null, 2)}\n`;
}

function writeIfChanged(relativePath, text) {
const filePath = path.join(repoRoot, relativePath);
if (fs.existsSync(filePath) && fs.readFileSync(filePath, 'utf8') === text) return false;
fs.writeFileSync(filePath, text);
return true;
}

function generatedKfd3Prebuild() {
const release = readJson(paths.release);
const prebuild = readJson(paths.kfd3Prebuild);
const interfaceDigest = `sha256:${sha256File(paths.kfd3Interface)}`;

prebuild.sourceRegistry = {
...(prebuild.sourceRegistry || {}),
version: release.npmVersion,
};
prebuild.collaborationInterfaceDigest = interfaceDigest;
if (prebuild.collaborationInterface && typeof prebuild.collaborationInterface === 'object') {
prebuild.collaborationInterface.digest = interfaceDigest;
}

return prebuild;
}

function generatedKfd1Witness(kfd3PrebuildText) {
const witness = readJson(paths.kfd1Witness);
const releaseSha = sha256File(paths.release);
const kfd3PrebuildSha = crypto.createHash('sha256').update(kfd3PrebuildText).digest('hex');
const surfaceSha = {
'package-manifest': sha256File(paths.packageJson),
'release-manifest': releaseSha,
'buildchain-config': sha256File(paths.buildchain),
'package-builder': sha256File(paths.platformPackage),
'release-verifier': sha256File(paths.releaseVerify),
'kfd3-artifact-verifier': sha256File(paths.kfd3ArtifactVerify),
'release-workflow': sha256File(paths.releaseWorkflow),
'kfd3-collaboration-interface': sha256File(paths.kfd3Interface),
'kfd3-prebuild-witness': kfd3PrebuildSha,
};

witness.contractWorld = {
...(witness.contractWorld || {}),
digest: `sha256:${releaseSha}`,
};
witness.standardContract = {
...(witness.standardContract || {}),
sha256: releaseSha,
};
witness.surfaces = (witness.surfaces || []).map((surface) => {
const sha = surfaceSha[surface.name];
if (!sha) {
throw new Error(`Unknown KFD-1 surface: ${surface.name}`);
}
return {
...surface,
sourceSha256: sha,
expectedSha256: sha,
};
});

return witness;
}

function buildExpectedTexts() {
const kfd3PrebuildText = jsonText(generatedKfd3Prebuild());
return {
[paths.kfd3Prebuild]: kfd3PrebuildText,
[paths.kfd1Witness]: jsonText(generatedKfd1Witness(kfd3PrebuildText)),
};
}

function check() {
const stale = [];
for (const [relativePath, expected] of Object.entries(buildExpectedTexts())) {
const current = fs.existsSync(path.join(repoRoot, relativePath))
? fs.readFileSync(path.join(repoRoot, relativePath), 'utf8')
: '';
if (current.replace(/\r\n/g, '\n') !== expected) stale.push(relativePath);
}

if (stale.length > 0) {
throw new Error(`KFD witness files are stale: ${stale.join(', ')}. Run corepack pnpm sync-kfd-witnesses.`);
}
console.log('libnode KFD witnesses ok');
}

function write() {
const changed = [];
for (const [relativePath, expected] of Object.entries(buildExpectedTexts())) {
if (writeIfChanged(relativePath, expected)) changed.push(relativePath);
}
console.log(
changed.length ? `updated KFD witnesses: ${changed.join(', ')}` : 'libnode KFD witnesses already up to date',
);
}

function main() {
const command = process.argv[2] || 'check';
useGitBlobContent = command === 'check' && process.env.GITHUB_ACTIONS === 'true';
if (command === 'check') return check();
if (command === 'write') return write();
throw new Error(`Unknown command: ${command}`);
}

try {
main();
} catch (error) {
console.error(error.message);
process.exit(1);
}
4 changes: 2 additions & 2 deletions buildchain.contract-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
"contract": "kungfu-buildchain-contract-lock",
"buildchain": {
"ref": "v2",
"resolvedSha": "6990341aaf93b51b936e5e66f380488d593daf6e",
"resolvedSha": "09694eed5ba1b2bcfd85fd7b805d42ea2fc9b72a",
"contract": "kungfu-buildchain-runtime-contract-world",
"contractDigest": "sha256:3a82cbfd0cf15f85dac51b6ab03e3c3ce20ca2f3355d5319d969c43758ebb900",
"contractDigest": "sha256:6b6cd5aab74bde21e88bf2a551557280954fa9fcacc298b875b56bbd9e1e04db",
"compatibilityDigest": "sha256:407d6d5ee6a96a34d2cc30db9ac64cf4b1819ab6d77bd7a57a07a124f22101ca",
"majorLine": "v2",
"compatibilityPolicy": "major-compatible",
Expand Down
1 change: 1 addition & 0 deletions buildchain.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ commands = [
timeout_minutes = 10
commands = [
"corepack pnpm verify-release",
"corepack pnpm verify-kfd-witnesses",
"corepack pnpm verify-package-source",
"git diff --check",
]
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
"prepare-node-source": "node .gyp/node-source-prepare.js",
"rebuild": "node .gyp/node-build.js rebuild",
"verify-release": "node .gyp/libnode-release-verify.js",
"sync-kfd-witnesses": "node .gyp/libnode-kfd-witnesses.js write",
"verify-kfd-witnesses": "node .gyp/libnode-kfd-witnesses.js check",
"verify-kfd3-artifact": "node .gyp/libnode-kfd3-artifact-verify.js",
"verify-package-source": "node .gyp/node-platform-package.js verify-source",
"format": "prettier --write --parser typescript .gyp/*.js src/js/*.js"
Expand Down