Skip to content

Contract Smoke Test #455

Contract Smoke Test

Contract Smoke Test #455

name: Contract Smoke Test
on:
schedule:
- cron: '0 2 * * *'
pull_request:
paths:
- 'contracts/**'
- '.github/workflows/contract-smoke.yml'
- 'docs/CONTRIBUTING.md'
push:
branches:
- main
- develop
paths:
- 'contracts/**'
- '.github/workflows/contract-smoke.yml'
- 'docs/CONTRIBUTING.md'
jobs:
soroban-testnet-smoke:
runs-on: ubuntu-latest
timeout-minutes: 10
env:
STELLAR_SECRET_KEY: ${{ secrets.STELLAR_TESTNET_SECRET_KEY }}
SOROBAN_RPC_URL: https://soroban-testnet.stellar.org
SOROBAN_NETWORK_PASSPHRASE: Test SDF Network ; September 2015
steps:
- uses: actions/checkout@v4
- name: Ensure testnet secret exists
run: |
if [ -z "${STELLAR_SECRET_KEY}" ]; then
echo "::error::Missing STELLAR_TESTNET_SECRET_KEY repository secret"
exit 1
fi
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- name: Cache Cargo and Soroban
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
~/.soroban
contracts/target
key: contract-smoke-${{ runner.os }}-${{ hashFiles('contracts/Cargo.lock', 'contracts/Cargo.toml') }}
restore-keys: |
contract-smoke-${{ runner.os }}-
- name: Install Soroban CLI
run: cargo install --locked soroban-cli
- name: Install cargo-deny
run: cargo install --locked cargo-deny
- name: Audit Rust dependencies
working-directory: ./contracts
run: |
cargo generate-lockfile
cargo deny check
- name: Build contract wasm
working-directory: ./contracts
run: cargo build --target wasm32-unknown-unknown --release
- name: Run benchmarks
working-directory: ./contracts
if: github.event_name == 'pull_request'
run: |
cargo test benchmark_ -- --nocapture > bench_output.txt || true
python3 -c '
import json
lines = [line.strip() for line in open("bench_output.txt") if "BENCHMARK_RESULT|" in line]
records = []
with open("bench_summary.md", "w") as f:
f.write("## Benchmark Results\n")
f.write("| Benchmark | CPU | Baseline CPU | Δ CPU | Mem | Baseline Mem | Δ Mem |\n")
f.write("|-----------|-----|--------------|-------|-----|--------------|-------|\n")
for line in lines:
parts = line.split("|")
name, cpu, base_cpu, mem, base_mem = parts[1], int(parts[2]), int(parts[3]), int(parts[4]), int(parts[5])
cpu_diff = (cpu - base_cpu) / base_cpu * 100
mem_diff = (mem - base_mem) / base_mem * 100
f.write(f"| `{name}` | {cpu:,} | {base_cpu:,} | {cpu_diff:+.2f}% | {mem:,} | {base_mem:,} | {mem_diff:+.2f}% |\n")
records.append({"benchmark": name, "cpu": cpu, "baseline_cpu": base_cpu, "mem": mem, "baseline_mem": base_mem})
with open("bench_results.json", "w") as f:
json.dump(records, f, indent=2)
'
cat bench_summary.md >> $GITHUB_STEP_SUMMARY
- name: Upload machine-readable benchmark JSON
uses: actions/upload-artifact@v4
if: github.event_name == 'pull_request'
with:
name: bench-results-json
path: contracts/bench_results.json
- name: Post benchmark summary
uses: marocchino/sticky-pull-request-comment@v2
if: github.event_name == 'pull_request'
with:
header: benchmark
path: contracts/bench_summary.md
- name: Deploy and initialize on testnet
working-directory: ./contracts
run: |
soroban network add testnet --global \
--rpc-url "${SOROBAN_RPC_URL}" \
--network-passphrase "${SOROBAN_NETWORK_PASSPHRASE}" || true
soroban keys add ci-deployer --global --secret-key "${STELLAR_SECRET_KEY}" || true
ADMIN_ADDRESS="$(soroban keys address ci-deployer --global)"
CONTRACT_ID="$(soroban contract deploy \
--wasm target/wasm32-unknown-unknown/release/portfolio_rebalancer.wasm \
--source ci-deployer \
--network testnet)"
if [ -z "${CONTRACT_ID}" ]; then
echo "::error::Contract deployment did not return a contract ID"
exit 1
fi
soroban contract invoke \
--id "${CONTRACT_ID}" \
--source ci-deployer \
--network testnet \
-- initialize \
--admin "${ADMIN_ADDRESS}" \
--reflector_address "${ADMIN_ADDRESS}"