forked from SO4-Markets/contracts
-
Notifications
You must be signed in to change notification settings - Fork 0
177 lines (138 loc) · 6.25 KB
/
Copy pathwasm-size.yml
File metadata and controls
177 lines (138 loc) · 6.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
name: WASM Size Budget
on:
pull_request:
branches: [main]
permissions:
pull-requests: write # needed to post the size-change comment
contents: read
jobs:
wasm-size:
name: Build & check WASM sizes
runs-on: ubuntu-latest
steps:
- name: Checkout PR branch
uses: actions/checkout@v4
with:
fetch-depth: 0 # full history so we can checkout the base
# ── Rust toolchain ────────────────────────────────────────────────────
- name: Install Rust stable + wasm32 target
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- name: Cache Cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
# ── Binaryen (wasm-opt) ───────────────────────────────────────────────
- name: Install wasm-opt
run: |
sudo apt-get update -q
sudo apt-get install -y binaryen
# ── Build HEAD (PR branch) ────────────────────────────────────────────
- name: Build contracts (PR)
run: cargo build --target wasm32-unknown-unknown --release
- name: Optimise WASM files (PR)
run: |
for f in target/wasm32-unknown-unknown/release/*.wasm; do
wasm-opt -O3 -o "$f" "$f"
done
- name: Record PR sizes
id: pr_sizes
run: |
mkdir -p /tmp/wasm-sizes
for f in target/wasm32-unknown-unknown/release/*.wasm; do
name=$(basename "$f" .wasm)
size=$(wc -c < "$f")
echo "$size" > "/tmp/wasm-sizes/pr_${name}"
done
# ── Build BASE (target branch) ────────────────────────────────────────
- name: Checkout base branch
run: git checkout "${{ github.base_ref }}"
- name: Build contracts (base)
run: cargo build --target wasm32-unknown-unknown --release
- name: Optimise WASM files (base)
run: |
for f in target/wasm32-unknown-unknown/release/*.wasm; do
wasm-opt -O3 -o "$f" "$f"
done
- name: Record base sizes
run: |
for f in target/wasm32-unknown-unknown/release/*.wasm; do
name=$(basename "$f" .wasm)
size=$(wc -c < "$f")
echo "$size" > "/tmp/wasm-sizes/base_${name}"
done
# ── Compare and report ────────────────────────────────────────────────
- name: Compare sizes and determine outcome
id: compare
run: |
python3 - <<'PYEOF'
import os, sys
size_dir = "/tmp/wasm-sizes"
files = set()
# Keep in sync with TEST_CONTRACTS in scripts/gen_baseline.py: these
# crates are test fixtures, not production contracts, and are exempt
# from the size budget.
TEST_CONTRACTS = {"test_faucet", "test_token"}
for fname in os.listdir(size_dir):
if fname.startswith("pr_"):
name = fname[3:] # strip "pr_" prefix to get contract name
if name not in TEST_CONTRACTS:
files.add(name)
WARN_THRESHOLD = 0.05 # 5%
BLOCK_THRESHOLD = 0.10 # 10%
rows = []
worst_ratio = 0.0
block = False
for contract in sorted(files):
pr_file = os.path.join(size_dir, f"pr_{contract}")
base_file = os.path.join(size_dir, f"base_{contract}")
pr_size = int(open(pr_file).read().strip())
if os.path.exists(base_file):
base_size = int(open(base_file).read().strip())
delta = pr_size - base_size
ratio = delta / base_size if base_size else 0
pct = ratio * 100
if ratio > BLOCK_THRESHOLD:
status = "🔴 BLOCK"
block = True
elif ratio > WARN_THRESHOLD:
status = "🟡 WARN"
elif delta < 0:
status = "🟢"
else:
status = "✅"
rows.append(f"| `{contract}` | {base_size:,} | {pr_size:,} | {delta:+,} | {pct:+.1f}% | {status} |")
worst_ratio = max(worst_ratio, ratio)
else:
rows.append(f"| `{contract}` | — | {pr_size:,} | +{pr_size:,} | new | 🆕 |")
table = "\n".join(rows)
comment = f"""## WASM Size Report
| Contract | Base (bytes) | PR (bytes) | Delta | Change | Status |
|---|---|---|---|---|---|
{table}
**Thresholds:** warn at +5%, block at +10% growth.
"""
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
f.write(f"block={'true' if block else 'false'}\n")
# Write multi-line output using a heredoc delimiter
delimiter = "EOF_SIZE_REPORT"
f.write(f"comment<<{delimiter}\n{comment}\n{delimiter}\n")
sys.exit(1 if block else 0)
PYEOF
# ── Post comment ──────────────────────────────────────────────────────
- name: Post size report as PR comment
if: always()
uses: marocchino/sticky-pull-request-comment@v2
with:
header: wasm-size-report
message: ${{ steps.compare.outputs.comment }}
# The compare step already exits 1 when block=true, so the job fails.
# The sticky comment step runs regardless (if: always()) so reviewers
# always see the table even when the build is blocked.