From 1fe5673ce51446cae3efed81a4d1ef170a5757ac Mon Sep 17 00:00:00 2001 From: openhands Date: Wed, 18 Mar 2026 13:11:33 +0000 Subject: [PATCH] fix: No forge compile verification in transpiler CI (#904) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - test_transpiler_clamping.sh: add Test 11 that runs forge build on the valid Solidity output from Test 6; fails if the transpiled contract does not compile (regression guard for #900) - test_inject_extraction.sh: add SCRIPT_DIR, then Test 5 that transpiles optimizer_seed.push3 and runs forge build on the generated contract; ensures the full push3→Solidity→compile pipeline stays green - .woodpecker/ci.yml: add transpiler-tests step that installs npm deps and runs both test scripts with forge on PATH Co-Authored-By: Claude Sonnet 4.6 --- .woodpecker/ci.yml | 13 +++++ .../test_inject_extraction.sh | 52 +++++++++++++++++++ .../test_transpiler_clamping.sh | 32 ++++++++++++ 3 files changed, 97 insertions(+) diff --git a/.woodpecker/ci.yml b/.woodpecker/ci.yml index 57c69b6..7f14b68 100644 --- a/.woodpecker/ci.yml +++ b/.woodpecker/ci.yml @@ -57,6 +57,19 @@ steps: # NOTE: contracts-base-sepolia step removed — requires base_sepolia_rpc secret # which is not configured. Re-add when RPC secret is provisioned. + - name: transpiler-tests + image: registry.niovi.voyage/harb/node-ci:latest + commands: + - | + bash -c ' + set -euo pipefail + export PATH=/root/.foundry/bin:$PATH + cd tools/push3-transpiler + npm install --silent + bash test_inject_extraction.sh + bash test_transpiler_clamping.sh + ' + - name: single-package-manager image: registry.niovi.voyage/harb/node-ci:latest commands: diff --git a/tools/push3-transpiler/test_inject_extraction.sh b/tools/push3-transpiler/test_inject_extraction.sh index fb826b9..2ed5610 100755 --- a/tools/push3-transpiler/test_inject_extraction.sh +++ b/tools/push3-transpiler/test_inject_extraction.sh @@ -5,6 +5,8 @@ # Exit: 0 if all tests pass, 1 if any fail. set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + PASS=0 FAIL=0 @@ -155,6 +157,56 @@ else PASS=$((PASS + 1)) fi +# ── Test 5: forge build on transpiled optimizer_seed.push3 ─────────────────── +echo "Test 5: forge build on transpiled optimizer_seed.push3 (compile regression guard)" + +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +TMPDIR_I5=$(mktemp -d) +trap 'rm -rf "$TMPDIR_I5"' EXIT + +if [ ! -d "$SCRIPT_DIR/node_modules" ]; then + (cd "$SCRIPT_DIR" && npm install --silent) +fi + +SOL_OUT="$TMPDIR_I5/OptimizerV3Push3.sol" +TRANSPILE_RC=0 +(cd "$SCRIPT_DIR" && node --loader ts-node/esm src/index.ts \ + "$REPO_ROOT/tools/push3-transpiler/optimizer_seed.push3" "$SOL_OUT") \ + >/dev/null 2>&1 || TRANSPILE_RC=$? + +if [ "$TRANSPILE_RC" -ne 0 ]; then + echo " FAIL: transpiler failed on optimizer_seed.push3" + FAIL=$((FAIL + 1)) +else + FORGE_BIN="$(command -v forge 2>/dev/null || true)" + if [ -z "$FORGE_BIN" ] && [ -x /root/.foundry/bin/forge ]; then + FORGE_BIN=/root/.foundry/bin/forge + fi + + if [ -z "$FORGE_BIN" ]; then + echo " SKIP: forge not found — add foundry bin to PATH to enable compile verification" + else + FORGE_DIR="$TMPDIR_I5/forge_verify" + mkdir -p "$FORGE_DIR/src" + printf '[profile.default]\nsrc = "src"\nout = "out"\nlibs = []\n' > "$FORGE_DIR/foundry.toml" + cp "$REPO_ROOT/onchain/src/IOptimizer.sol" "$FORGE_DIR/src/" + cp "$SOL_OUT" "$FORGE_DIR/src/OptimizerV3Push3.sol" + + FORGE_OUT="" + FORGE_RC=0 + FORGE_OUT=$(cd "$FORGE_DIR" && "$FORGE_BIN" build 2>&1) || FORGE_RC=$? + + if [ "$FORGE_RC" -eq 0 ]; then + echo " PASS: forge build succeeded on transpiled optimizer_seed.push3" + PASS=$((PASS + 1)) + else + echo " FAIL: forge build failed on transpiled optimizer_seed.push3" + echo "$FORGE_OUT" | sed 's/^/ /' + FAIL=$((FAIL + 1)) + fi + fi +fi + # ── Summary ────────────────────────────────────────────────────────────────── echo "" echo "Results: $PASS passed, $FAIL failed" diff --git a/tools/push3-transpiler/test_transpiler_clamping.sh b/tools/push3-transpiler/test_transpiler_clamping.sh index 93da1b7..9fad527 100755 --- a/tools/push3-transpiler/test_transpiler_clamping.sh +++ b/tools/push3-transpiler/test_transpiler_clamping.sh @@ -185,6 +185,38 @@ assert_contains \ "$STDERR" \ "anchorWidth literal (-1) is outside uint24 range [0, 16777215]" +# ── Test 11: forge build — transpiler output compiles (regression for #900) ── +echo "Test 11: forge build on valid transpiler output (regression for #900)" + +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +FORGE_BIN="$(command -v forge 2>/dev/null || true)" +if [ -z "$FORGE_BIN" ] && [ -x /root/.foundry/bin/forge ]; then + FORGE_BIN=/root/.foundry/bin/forge +fi + +if [ -z "$FORGE_BIN" ]; then + echo " SKIP: forge not found — add foundry bin to PATH to enable compile verification" +else + FORGE_DIR="$TMPDIR_T/forge_verify" + mkdir -p "$FORGE_DIR/src" + printf '[profile.default]\nsrc = "src"\nout = "out"\nlibs = []\n' > "$FORGE_DIR/foundry.toml" + cp "$REPO_ROOT/onchain/src/IOptimizer.sol" "$FORGE_DIR/src/" + cp "$OUTPUT_6" "$FORGE_DIR/src/OptimizerV3Push3.sol" + + FORGE_OUT="" + FORGE_RC=0 + FORGE_OUT=$(cd "$FORGE_DIR" && "$FORGE_BIN" build 2>&1) || FORGE_RC=$? + + if [ "$FORGE_RC" -eq 0 ]; then + echo " PASS: forge build succeeded on transpiled contract" + PASS=$((PASS + 1)) + else + echo " FAIL: forge build failed — transpiled contract does not compile" + echo "$FORGE_OUT" | sed 's/^/ /' + FAIL=$((FAIL + 1)) + fi +fi + # ── Summary ────────────────────────────────────────────────────────────────── echo "" echo "Results: $PASS passed, $FAIL failed"