Skip to content

Commit cee37c6

Browse files
committed
refactor: harden and optimize check-upgrade-hygiene script
- Replace 8 per-contract sed calls with single-pass awk extraction (fixes latent bug where multiple matches could silently corrupt values, and [0-9]* matching zero digits) - Pre-compile both roots in parallel (forge build) so all forge inspect calls are cache hits — halves compilation wall time in CI - Handle forge inspect failures gracefully (report + continue) instead of aborting the entire script under set -e - Remove unnecessary chmod +x in workflow (file already has exec bit)
1 parent c9aff6f commit cee37c6

File tree

2 files changed

+36
-21
lines changed

2 files changed

+36
-21
lines changed

.github/workflows/contracts-upgrade-hygiene.yml

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,7 @@ jobs:
9393
cp /tmp/FHEVMHostAddresses.sol main-branch/host-contracts/addresses/FHEVMHostAddresses.sol
9494
9595
- name: Run upgrade hygiene check
96-
run: |
97-
chmod +x ci/check-upgrade-hygiene.sh
98-
./ci/check-upgrade-hygiene.sh main-branch/host-contracts host-contracts
96+
run: ./ci/check-upgrade-hygiene.sh main-branch/host-contracts host-contracts
9997

10098
gateway-contracts:
10199
name: contracts-upgrade-hygiene/gateway-contracts
@@ -150,6 +148,4 @@ jobs:
150148
cp /tmp/GatewayAddresses.sol main-branch/gateway-contracts/addresses/GatewayAddresses.sol
151149
152150
- name: Run upgrade hygiene check
153-
run: |
154-
chmod +x ci/check-upgrade-hygiene.sh
155-
./ci/check-upgrade-hygiene.sh main-branch/gateway-contracts gateway-contracts
151+
run: ./ci/check-upgrade-hygiene.sh main-branch/gateway-contracts gateway-contracts

ci/check-upgrade-hygiene.sh

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,26 @@ fi
2929

3030
ERRORS=0
3131

32-
extract_const() {
33-
local file="$1" const="$2"
34-
sed -n "s/.*${const}[[:space:]]*=[[:space:]]*\([0-9]*\).*/\1/p" "$file"
32+
# Extract all four version constants from a .sol file in a single pass.
33+
# Returns: REINITIALIZER_VERSION MAJOR_VERSION MINOR_VERSION PATCH_VERSION
34+
extract_versions() {
35+
awk '
36+
/REINITIALIZER_VERSION[[:space:]]*=[[:space:]]*[0-9]/ { gsub(/[^0-9]/,"",$NF); reinit=$NF }
37+
/MAJOR_VERSION[[:space:]]*=[[:space:]]*[0-9]/ { gsub(/[^0-9]/,"",$NF); major=$NF }
38+
/MINOR_VERSION[[:space:]]*=[[:space:]]*[0-9]/ { gsub(/[^0-9]/,"",$NF); minor=$NF }
39+
/PATCH_VERSION[[:space:]]*=[[:space:]]*[0-9]/ { gsub(/[^0-9]/,"",$NF); patch=$NF }
40+
END { print reinit, major, minor, patch }
41+
' "$1"
3542
}
3643

44+
# Pre-compile both roots in parallel so all forge inspect calls are cache hits.
45+
forge build --root "$MAIN_DIR" &
46+
pid_main=$!
47+
forge build --root "$PR_DIR" &
48+
pid_pr=$!
49+
wait "$pid_main" || { echo "::error::forge build failed for $MAIN_DIR"; exit 1; }
50+
wait "$pid_pr" || { echo "::error::forge build failed for $PR_DIR"; exit 1; }
51+
3752
for name in $(jq -r '.[]' "$PR_DIR/upgrade-manifest.json"); do
3853
echo "::group::Checking $name"
3954

@@ -54,15 +69,9 @@ for name in $(jq -r '.[]' "$PR_DIR/upgrade-manifest.json"); do
5469
continue
5570
fi
5671

57-
# --- Extract version constants from both ---
58-
main_reinit=$(extract_const "$main_sol" "REINITIALIZER_VERSION")
59-
pr_reinit=$(extract_const "$pr_sol" "REINITIALIZER_VERSION")
60-
main_major=$(extract_const "$main_sol" "MAJOR_VERSION")
61-
pr_major=$(extract_const "$pr_sol" "MAJOR_VERSION")
62-
main_minor=$(extract_const "$main_sol" "MINOR_VERSION")
63-
pr_minor=$(extract_const "$pr_sol" "MINOR_VERSION")
64-
main_patch=$(extract_const "$main_sol" "PATCH_VERSION")
65-
pr_patch=$(extract_const "$pr_sol" "PATCH_VERSION")
72+
# --- Extract version constants from both (single pass per file) ---
73+
read -r main_reinit main_major main_minor main_patch < <(extract_versions "$main_sol")
74+
read -r pr_reinit pr_major pr_minor pr_patch < <(extract_versions "$pr_sol")
6675

6776
for var in main_reinit pr_reinit main_major pr_major main_minor pr_minor main_patch pr_patch; do
6877
if [ -z "${!var}" ]; then
@@ -73,9 +82,19 @@ for name in $(jq -r '.[]' "$PR_DIR/upgrade-manifest.json"); do
7382
fi
7483
done
7584

76-
# --- Compare bytecodes (paths relative to --root) ---
77-
main_bytecode=$(forge inspect "contracts/${name}.sol:$name" --root "$MAIN_DIR" deployedBytecode)
78-
pr_bytecode=$(forge inspect "contracts/${name}.sol:$name" --root "$PR_DIR" deployedBytecode)
85+
# --- Compare bytecodes (paths relative to --root, builds are cached) ---
86+
if ! main_bytecode=$(forge inspect "contracts/${name}.sol:$name" --root "$MAIN_DIR" deployedBytecode 2>&1); then
87+
echo "::error::Failed to inspect $name on main: $main_bytecode"
88+
ERRORS=$((ERRORS + 1))
89+
echo "::endgroup::"
90+
continue
91+
fi
92+
if ! pr_bytecode=$(forge inspect "contracts/${name}.sol:$name" --root "$PR_DIR" deployedBytecode 2>&1); then
93+
echo "::error::Failed to inspect $name on PR: $pr_bytecode"
94+
ERRORS=$((ERRORS + 1))
95+
echo "::endgroup::"
96+
continue
97+
fi
7998

8099
bytecode_changed=false
81100
if [ "$main_bytecode" != "$pr_bytecode" ]; then

0 commit comments

Comments
 (0)