diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cfb3230..6ad3dfb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,6 +26,10 @@ jobs: buildchain-contract-lock-path: buildchain.contract-lock.json buildchain-contract-drift-issue-mode: compatible-and-breaking artifact-transfer-mode: s3-to-github-artifacts + checkout-cache-mode: auto + checkout-cache-mirror-url-template: ${{ vars.BUILDCHAIN_CHECKOUT_CACHE_MIRROR_URL_TEMPLATE }} + checkout-cache-fallback: github + checkout-cache-timeout-seconds: 60 setup-node: true node-version: '24' install-command: node .gyp/buildchain-install.js "${{ vars.KF_NODE_GIT_URL }}" "${{ vars.KF_NODE_REFERENCE }}" diff --git a/.github/workflows/release-verify.yaml b/.github/workflows/release-verify.yaml index 5f85432..2058721 100644 --- a/.github/workflows/release-verify.yaml +++ b/.github/workflows/release-verify.yaml @@ -24,6 +24,10 @@ jobs: buildchain-contract-lock-path: buildchain.contract-lock.json buildchain-contract-drift-issue-mode: compatible-and-breaking artifact-transfer-mode: s3-to-github-artifacts + checkout-cache-mode: auto + checkout-cache-mirror-url-template: ${{ vars.BUILDCHAIN_CHECKOUT_CACHE_MIRROR_URL_TEMPLATE }} + checkout-cache-fallback: github + checkout-cache-timeout-seconds: 60 setup-node: true node-version: '24' install-command: node .gyp/buildchain-install.js "${{ vars.KF_NODE_GIT_URL }}" "${{ vars.KF_NODE_REFERENCE }}" diff --git a/.gyp/build-env.js b/.gyp/build-env.js index 2890c66..cb1a35d 100644 --- a/.gyp/build-env.js +++ b/.gyp/build-env.js @@ -87,8 +87,12 @@ function downloadWindowsPython(url, archivePath, env = process.env) { ); } -function usePython(env, pythonExe) { - env.PYTHON = env.PYTHON || pythonExe; +function usePython(env, pythonExe, options = {}) { + if (options.force) { + env.PYTHON = pythonExe; + } else { + env.PYTHON = env.PYTHON || pythonExe; + } prependPath(env, path.dirname(pythonExe)); return pythonExe; } @@ -123,6 +127,10 @@ function ensureWindowsPythonFromCache(env = process.env) { function prepareWindowsPythonEnv(env = process.env) { if (process.platform !== 'win32') return ''; + const configuredPython = env.KF_WINDOWS_PYTHON_EXE || env.KF_WINDOWS_SYSTEM_PYTHON || ''; + if (configuredPython && fs.existsSync(configuredPython)) { + return usePython(env, configuredPython, { force: true }); + } const existingPython = env.PYTHON || commandExists('python.exe', env); if (existingPython) return usePython(env, existingPython); diff --git a/.gyp/node-make.js b/.gyp/node-make.js index 19bf8b5..af8fdb2 100644 --- a/.gyp/node-make.js +++ b/.gyp/node-make.js @@ -199,7 +199,12 @@ const buildWin = () => { const buildUnix = () => { cleanNodeBuildState(); prepareCompilerCache(); - run('sh', [path.join('.', 'configure'), '--shared'], { cwd: nodeSrcDir }); + const configureScript = path.join('.', 'configure'); + if (process.platform === 'linux' && fs.existsSync('/usr/bin/python3')) { + run('/usr/bin/python3', [configureScript, '--shared'], { cwd: nodeSrcDir }); + } else { + run('sh', [configureScript, '--shared'], { cwd: nodeSrcDir }); + } run('make', ['-j', `${buildJobs()}`], { cwd: nodeSrcDir }); showCompilerCacheStats(); }; diff --git a/.gyp/node-source-prepare.js b/.gyp/node-source-prepare.js index 93889a2..5a0fea0 100644 --- a/.gyp/node-source-prepare.js +++ b/.gyp/node-source-prepare.js @@ -122,21 +122,38 @@ function usableReferencePath() { return ''; } +function useReferenceAlternates(referencePath) { + if (!referencePath) return; + const referenceObjects = output('git', ['-C', referencePath, 'rev-parse', '--git-path', 'objects']); + if (!referenceObjects) return; + const referenceObjectsPath = path.isAbsolute(referenceObjects) + ? referenceObjects + : path.resolve(referencePath, referenceObjects); + const alternates = output('git', ['-C', nodeSrcDir, 'rev-parse', '--git-path', 'objects/info/alternates']); + if (!alternates) return; + const alternatesPath = path.isAbsolute(alternates) ? alternates : path.resolve(nodeSrcDir, alternates); + fs.mkdirSync(path.dirname(alternatesPath), { recursive: true }); + fs.writeFileSync(alternatesPath, `${referenceObjectsPath}\n`); +} + function updateFrom(url, referencePath) { prepareGitNetworkEnv(url); configureSubmodule(url); if (!currentNodeHead()) { - const cloneArgs = ['clone', '--no-checkout', '--progress']; - if (referencePath) { - cloneArgs.push('--reference', referencePath); + fs.mkdirSync(nodeSrcDir, { recursive: true }); + const initResult = run('git', ['-C', nodeSrcDir, 'init'], { check: false }); + if (initResult.status !== 0) { + console.warn(`node git init failed for ${url}`); + return false; } - cloneArgs.push(url, 'node'); - const cloneResult = run('git', cloneArgs, { check: false }); - if (cloneResult.status !== 0) { - console.warn(`node clone failed from ${url}`); + run('git', ['-C', nodeSrcDir, 'remote', 'remove', 'origin'], { check: false }); + const remoteResult = run('git', ['-C', nodeSrcDir, 'remote', 'add', 'origin', url], { check: false }); + if (remoteResult.status !== 0) { + console.warn(`node remote setup failed for ${url}`); return false; } + useReferenceAlternates(referencePath); } else { run('git', ['-C', nodeSrcDir, 'remote', 'set-url', 'origin', url], { check: false }); } @@ -147,6 +164,7 @@ function updateFrom(url, referencePath) { '-C', nodeSrcDir, 'fetch', + '--depth=1', '--tags', '--force', '--progress', diff --git a/README.md b/README.md index f929b53..912f2fc 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,17 @@ job. The workflow does not use `NPM_PUSH_TOKEN` or npm dist-tag recovery tokens for the normal path; package access is authorized by the trusted publisher records on npm for this repository and workflow file. -For self-hosted runners, set `KF_NODE_GIT_URL` to a local network Git service when available. `KF_NODE_REFERENCE` can also point at a runner-local bare mirror to reduce repeated object transfer. If those variables are not set, the prepare step falls back to the public Node.js GitHub repository. +For self-hosted runners, set `BUILDCHAIN_CHECKOUT_CACHE_MIRROR_URL_TEMPLATE` +to the Buildchain locked source checkout mirror template, such as +`http://192.168.100.222:8088/git-mirrors/{repo}.git`, so the release source +checkout can be resolved from the local network before falling back to GitHub. +Set `KF_NODE_GIT_URL` to a local Node.js Git mirror when available. +Use a smart Git endpoint such as `git://192.168.100.222/node.git` for this +value; the static HTTP mirror is only suitable for Buildchain source checkout +and does not support shallow tag fetches. `KF_NODE_REFERENCE` can also point at +a runner-local bare mirror to reduce repeated object transfer. If those +variables are not set, the prepare step falls back to the public Node.js GitHub +repository. Compiler caching is enabled opportunistically with `KF_COMPILER_CACHE=auto` in `buildchain.toml`. Linux and macOS use `ccache` when it is installed on the runner. Windows uses Node.js `vcbuild.bat ccache ` mode when `ccache.exe` is available; set `KF_NODE_WIN_CCACHE_PATH` when the verified `ccache.exe`/`cl.exe` wrapper directory is not on `PATH`. Set `KF_DISABLE_COMPILER_CACHE=true` to force a clean uncached build. Unix builds default to `make -j `; set `KF_BUILD_JOBS=` when a runner needs a lower or higher explicit job count. diff --git a/buildchain.contract-lock.json b/buildchain.contract-lock.json index 7e84350..2d4cf72 100644 --- a/buildchain.contract-lock.json +++ b/buildchain.contract-lock.json @@ -3,13 +3,13 @@ "contract": "kungfu-buildchain-contract-lock", "buildchain": { "ref": "v2", - "resolvedSha": "c92cf5d31c544dcde3dc7a11151a90e8a5f91d25", + "resolvedSha": "6990341aaf93b51b936e5e66f380488d593daf6e", "contract": "kungfu-buildchain-runtime-contract-world", - "contractDigest": "sha256:f289f70ad8c2b95a05f8309378da51ec5641c1ea7a145670137d096285b70dcd", - "compatibilityDigest": "sha256:36421b592a782decbfe31a7d8d42d70ce1100a56a2c4f4a0ccc21f0617dc72bf", + "contractDigest": "sha256:3a82cbfd0cf15f85dac51b6ab03e3c3ce20ca2f3355d5319d969c43758ebb900", + "compatibilityDigest": "sha256:407d6d5ee6a96a34d2cc30db9ac64cf4b1819ab6d77bd7a57a07a124f22101ca", "majorLine": "v2", "compatibilityPolicy": "major-compatible", - "acceptedAt": "2026-07-07T00:00:00.000Z", + "acceptedAt": "2026-07-08T00:00:00.000Z", "surfaces": [ { "id": "reusable-build", @@ -21,6 +21,11 @@ "kind": "workflow", "breakingDigest": "sha256:403d2fcdb0c5eabe749e89102defad69745f70a1556707bec7831fcc2e9fa8f8" }, + { + "id": "web-surface", + "kind": "workflow", + "breakingDigest": "sha256:82ee63cb336e40d832dfff4a1c5e6cbfa221a4fc8b2359990033bc931bffc43a" + }, { "id": "promote-buildchain-ref-action", "kind": "action", @@ -54,7 +59,17 @@ { "id": "buildchain-cli", "kind": "cli", - "breakingDigest": "sha256:097db3e67509bedda8c6548bf1edfbfcf57f7b5510520b6a7b7e078d7ec087c8" + "breakingDigest": "sha256:90a73892b2d6c214048448d5f45df75639bdf7b7e8fefd9c596e04b087407bcc" + }, + { + "id": "homebrew-distribution-index", + "kind": "node-api", + "breakingDigest": "sha256:148c0387ff4cea76433bbde80cd9d77c5aa67e1a29856ced33e4d819366f2213" + }, + { + "id": "readme-badge-facts", + "kind": "node-api", + "breakingDigest": "sha256:bcd72ad6dfba8013c96f8b2f7b0a307d2e7713972a1219348f0d5ecc493939a0" }, { "id": "agent-manual-registry", diff --git a/buildchain.toml b/buildchain.toml index 9dc388f..72324e2 100644 --- a/buildchain.toml +++ b/buildchain.toml @@ -27,6 +27,7 @@ main_package = "@kungfu-tech/libnode" [lifecycle.env] KF_SKIP_FALLBACK_BUILD = "true" KF_COMPILER_CACHE = "auto" +KF_WINDOWS_PYTHON_EXE = "C:/Users/dkr/AppData/Local/Programs/Python/Python314/python.exe" [diagnostics.native] enabled = true diff --git a/libnode.release.json b/libnode.release.json index 26d754c..a9d5054 100644 --- a/libnode.release.json +++ b/libnode.release.json @@ -4,5 +4,5 @@ "nodeTag": "v22.22.3", "nodeCommit": "fdfa0ff0dbaf0fbf4d7d6d89a2ab807f3177fa5c", "libnodeRevision": 3, - "npmVersion": "22.22.3-kf.3-alpha.14" + "npmVersion": "22.22.3-kf.3-alpha.15" } diff --git a/package.json b/package.json index 2d94bb0..95e409c 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "name": "kungfu-trader", "email": "info@kungfu.link" }, - "version": "22.22.3-kf.3-alpha.14", + "version": "22.22.3-kf.3-alpha.15", "description": "Build shared node lib", "license": "Apache-2.0", "main": "src/js/index.js",