Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,24 @@ jobs:
with:
targets: wasm32v1-none
- uses: Swatinem/rust-cache@v2
- name: Install wasm-opt
run: sudo apt-get update && sudo apt-get install -y binaryen
- name: Build production WASM artifacts
run: ./scripts/build_wasm.sh
- name: Print WASM artifact sizes
run: |
{
echo "## Optimized WASM Artifacts"
echo ""
find target -name '*.wasm' -type f | sort | while read -r f; do
size=$(stat -c%s "$f")
echo "- \`$f\`: $size bytes"
done
} >> "$GITHUB_STEP_SUMMARY"
find target -name '*.wasm' -type f | sort | while read -r f; do
size=$(stat -c%s "$f")
echo "$f: $size bytes"
done

test:
name: Tests
Expand All @@ -54,3 +70,39 @@ jobs:
- uses: Swatinem/rust-cache@v2
- name: Run tests
run: cargo test

audit:
name: Dependency Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Install cargo-audit
run: cargo install cargo-audit
- name: Run cargo audit
run: cargo audit

coverage:
name: Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: Install tarpaulin
run: cargo install cargo-tarpaulin --features nocoverage-compression
- name: Run coverage
run: cargo tarpaulin --all-features --workspace --timeout 120 --out Stdout

sdk-parity:
name: SDK Error Code Parity
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Check SDK error code parity
run: python3 scripts/check_error_parity.py
47 changes: 47 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,53 @@ make check

`make check` must succeed with **zero warnings** before opening a PR. The CI pipeline enforces this automatically.

## Dependency Scanning

```bash
# Install the audit tool
cargo install cargo-audit

# Scan for known security advisories
cargo audit
```

`cargo audit` must pass with **zero advisories** before opening a PR. Fix any reported advisories as separate issues.

## Coverage

```bash
# Install the coverage tool
cargo install cargo-tarpaulin --features nocoverage-compression

# Run coverage across the workspace
cargo tarpaulin --all-features --workspace --timeout 120
```

Coverage results are reported in CI. There is no enforced minimum threshold yet; proposing one is welcome.

## SDK Error Code Parity

```bash
# Verify that every error code in the Rust contract has a matching entry in the SDK
python3 scripts/check_error_parity.py
```

When adding a new `ContractError` variant, always update `sdk/error-codes.ts` to keep the parity check green.

## Local CI Workflow

To reproduce the full CI pipeline locally before pushing:

```bash
cargo fmt --all -- --check
cargo clippy --all-targets -- -D warnings
cargo test
./scripts/build_wasm.sh
cargo audit
cargo tarpaulin --all-features --workspace --timeout 120
python3 scripts/check_error_parity.py
```

---

## Code Style Rules
Expand Down
18 changes: 13 additions & 5 deletions scripts/build_wasm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,25 @@ fi

find "$ARTIFACT_DIR" -maxdepth 1 -type f -name '*.wasm' -print | sort

if [ "$OPTIMIZE" = "true" ] && command -v wasm-opt >/dev/null 2>&1; then
if [ "$OPTIMIZE" = "true" ]; then
if ! command -v wasm-opt >/dev/null 2>&1; then
echo "error: wasm-opt not available; install binaryen to enable post-build wasm optimization." >&2
exit 1
fi
echo "Found wasm-opt, optimizing generated artifacts..."
while read -r wasm_file; do
opt_file="${wasm_file%.wasm}.opt.wasm"
wasm-opt -Oz -o "$opt_file" "$wasm_file"
printf 'Optimized %s -> %s\n' "$wasm_file" "$opt_file"
done < <(find "$ARTIFACT_DIR" -maxdepth 1 -type f -name '*.wasm' | sort)
else
if [ "$OPTIMIZE" = "true" ]; then
echo "wasm-opt not available; skipping post-build wasm optimization."
fi
fi

printf '\nProduction WASM build complete. Artifacts in %s\n' "$ARTIFACT_DIR"

if [ "$OPTIMIZE" = "true" ]; then
printf '\nOptimized WASM sizes:\n'
find "$ARTIFACT_DIR" -maxdepth 1 -type f -name '*.wasm' -print | sort | while read -r wasm_file; do
size=$(stat -c%s "$wasm_file" 2>/dev/null || stat -f%z "$wasm_file" 2>/dev/null || echo "unknown")
printf ' %s: %s bytes\n' "$wasm_file" "$size"
done
fi
42 changes: 42 additions & 0 deletions scripts/check_error_parity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env python3
"""Check that error codes in errors.rs match those in sdk/error-codes.ts."""

import re
import sys


def extract_rust_codes(path):
codes = set()
with open(path) as f:
for line in f:
stripped = line.strip()
if re.match(r'^\s*[A-Za-z_][A-Za-z0-9_]*\s*=\s*\d+\s*,?\s*$', stripped):
code = int(re.search(r'=\s*(\d+)', stripped).group(1))
codes.add(code)
return codes


def extract_ts_codes(path):
codes = set()
with open(path) as f:
for line in f:
stripped = line.strip()
if m := re.match(r'^\s*(\d+)\s*:\s*\{', stripped):
codes.add(int(m.group(1)))
return codes


rust_codes = extract_rust_codes('contracts/marketx/src/errors.rs')
ts_codes = extract_ts_codes('sdk/error-codes.ts')

missing_in_ts = sorted(rust_codes - ts_codes)
missing_in_rust = sorted(ts_codes - rust_codes)

if missing_in_ts or missing_in_rust:
if missing_in_ts:
print(f'Error: codes in Rust but missing in SDK: {missing_in_ts}')
if missing_in_rust:
print(f'Error: codes in SDK but missing in Rust: {missing_in_rust}')
sys.exit(1)

print('SDK error code parity check passed.')
Loading