Skip to content

Commit 868e7fb

Browse files
committed
fix(ci): strip ANSI codes from forge inspect output
Forge may prepend compilation progress messages with ANSI escape codes to stdout. Extract only the hex bytecode (0x...) from the output and pass NO_COLOR=1 to suppress colored output. This fixes the false positive where GatewayConfig bytecode appeared different between main and PR due to ANSI codes in the PR-side output.
1 parent 24822bb commit 868e7fb

File tree

1 file changed

+6
-28
lines changed

1 file changed

+6
-28
lines changed

ci/check-upgrade-hygiene.ts

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import { readFileSync, existsSync } from "fs";
66
import { execSync } from "child_process";
7-
import { createHash } from "crypto";
87
import { join } from "path";
98

109
const [mainDir, prDir] = process.argv.slice(2);
@@ -32,10 +31,14 @@ function extractVersions(filePath: string) {
3231

3332
function forgeInspect(contract: string, root: string): string | null {
3433
try {
35-
return execSync(`forge inspect "contracts/${contract}.sol:${contract}" --root "${root}" deployedBytecode`, {
34+
const raw = execSync(`forge inspect "contracts/${contract}.sol:${contract}" --root "${root}" deployedBytecode`, {
3635
encoding: "utf-8",
3736
stdio: ["pipe", "pipe", "pipe"],
38-
}).trim();
37+
env: { ...process.env, NO_COLOR: "1" },
38+
});
39+
// Extract hex bytecode — forge may prepend ANSI codes or compilation progress to stdout
40+
const match = raw.match(/0x[0-9a-fA-F]+/);
41+
return match ? match[0] : null;
3942
} catch (e: any) {
4043
if (e.stderr) console.error(String(e.stderr));
4144
return null;
@@ -90,31 +93,6 @@ for (const name of contracts) {
9093
}
9194

9295
const bytecodeChanged = mainBytecode !== prBytecode;
93-
94-
if (bytecodeChanged) {
95-
const sha = (s: string) => createHash("sha256").update(s).digest("hex").slice(0, 12);
96-
console.log(` main bytecode: len=${mainBytecode.length} sha=${sha(mainBytecode)}`);
97-
console.log(` PR bytecode: len=${prBytecode.length} sha=${sha(prBytecode)}`);
98-
// Find first divergence point
99-
for (let i = 0; i < Math.min(mainBytecode.length, prBytecode.length); i++) {
100-
if (mainBytecode[i] !== prBytecode[i]) {
101-
console.log(` first diff at offset ${i}: main=...${mainBytecode.slice(Math.max(0, i - 10), i + 10)}... pr=...${prBytecode.slice(Math.max(0, i - 10), i + 10)}...`);
102-
break;
103-
}
104-
}
105-
// Check key files match
106-
for (const f of ["foundry.toml", "addresses/GatewayAddresses.sol"]) {
107-
const mp = join(mainDir, f), pp = join(prDir, f);
108-
const mh = existsSync(mp) ? sha(readFileSync(mp, "utf-8")) : "MISSING";
109-
const ph = existsSync(pp) ? sha(readFileSync(pp, "utf-8")) : "MISSING";
110-
console.log(` ${f}: main=${mh} pr=${ph} ${mh === ph ? "MATCH" : "MISMATCH"}`);
111-
}
112-
// Check source files match
113-
const mSrcHash = sha(readFileSync(mainSol, "utf-8"));
114-
const pSrcHash = sha(readFileSync(prSol, "utf-8"));
115-
console.log(` ${name}.sol: main=${mSrcHash} pr=${pSrcHash} ${mSrcHash === pSrcHash ? "MATCH" : "MISMATCH"}`);
116-
}
117-
11896
const reinitChanged = mainV.REINITIALIZER_VERSION !== prV.REINITIALIZER_VERSION;
11997
const versionChanged =
12098
mainV.MAJOR_VERSION !== prV.MAJOR_VERSION ||

0 commit comments

Comments
 (0)