From 313187fcdfb3ac617558eb35415b32d5c09882e8 Mon Sep 17 00:00:00 2001 From: Lyon <88232613+pikasTech@users.noreply.github.com> Date: Tue, 23 Jun 2026 17:28:02 +0800 Subject: [PATCH] fix(agentrun): include source in env identity (#743) Co-authored-by: Codex --- config/agentrun.yaml | 4 ++++ scripts/src/agentrun.ts | 31 +++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/config/agentrun.yaml b/config/agentrun.yaml index 1c07f94a..8b460c35 100644 --- a/config/agentrun.yaml +++ b/config/agentrun.yaml @@ -135,6 +135,8 @@ controlPlane: - deploy/runtime/boot/agentrun-boot.sh - deploy/runtime/boot/agentrun-mgr.sh - deploy/runtime/boot/agentrun-runner.sh + - src + - scripts - package.json - bun.lock - tsconfig.json @@ -314,6 +316,8 @@ controlPlane: - deploy/runtime/boot/agentrun-boot.sh - deploy/runtime/boot/agentrun-mgr.sh - deploy/runtime/boot/agentrun-runner.sh + - src + - scripts - package.json - bun.lock - tsconfig.json diff --git a/scripts/src/agentrun.ts b/scripts/src/agentrun.ts index a42d1420..125d7b0d 100644 --- a/scripts/src/agentrun.ts +++ b/scripts/src/agentrun.ts @@ -3735,12 +3735,39 @@ function yamlLaneBuildImageSubmitScript(spec: AgentRunLaneSpec, sourceCommit: st "git checkout \"$source_commit\"", "env_identity=$(ENV_IDENTITY_FILES=\"$env_identity_files\" BUILD_ARGS_JSON=\"$build_args_json\" node <<'NODE'", "const { createHash } = require('node:crypto');", - "const { readFileSync, existsSync } = require('node:fs');", + "const { readFileSync, existsSync, lstatSync, readdirSync } = require('node:fs');", + "const { join } = require('node:path');", "const files = JSON.parse(process.env.ENV_IDENTITY_FILES || '[]');", "const buildArgs = JSON.parse(process.env.BUILD_ARGS_JSON || '[]');", "const hash = createHash('sha256');", + "const skipDirNames = new Set(['.git', '.worktree', '.state', 'node_modules', 'coverage', 'tmp', '.tmp']);", + "function collectIdentityFiles(input) {", + " if (!existsSync(input)) return [{ path: input, missing: true }];", + " const stat = lstatSync(input);", + " if (stat.isFile()) return [{ path: input, missing: false }];", + " if (!stat.isDirectory()) return [{ path: input, missing: true }];", + " const out = [];", + " const stack = [input];", + " while (stack.length > 0) {", + " const dir = stack.pop();", + " const entries = readdirSync(dir, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));", + " for (const entry of entries) {", + " if (entry.isDirectory() && skipDirNames.has(entry.name)) continue;", + " const child = join(dir, entry.name);", + " if (entry.isDirectory()) stack.push(child);", + " else if (entry.isFile()) out.push({ path: child, missing: false });", + " }", + " }", + " return out.sort((left, right) => left.path.localeCompare(right.path));", + "}", "for (const item of buildArgs) { hash.update('build-arg'); hash.update('\\0'); hash.update(item); hash.update('\\0'); }", - "for (const file of files) { hash.update(file); hash.update('\\0'); if (existsSync(file)) hash.update(readFileSync(file)); hash.update('\\0'); }", + "for (const file of files) {", + " for (const entry of collectIdentityFiles(file)) {", + " hash.update(entry.path); hash.update('\\0');", + " if (!entry.missing) hash.update(readFileSync(entry.path));", + " hash.update('\\0');", + " }", + "}", "process.stdout.write(hash.digest('hex').slice(0, 24));", "NODE", ")",