Skip to content

Merge branch 'main' into feature/issue-382-docker-multistage #1

Merge branch 'main' into feature/issue-382-docker-multistage

Merge branch 'main' into feature/issue-382-docker-multistage #1

Workflow file for this run

name: Contract CI

Check failure on line 1 in .github/workflows/contract-ci.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/contract-ci.yml

Invalid workflow file

(Line: 101, Col: 12): Job 'optimize' depends on unknown job 'build-wasm'.
# Runs on every PR against main and every push to main.
# Fuzz job is gated to the nightly schedule only.
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
# Nightly fuzz run at 02:00 UTC
- cron: '0 2 * * *'
# Cancel in-flight runs for the same ref on new push
concurrency:
group: contract-ci-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
RUSTFLAGS: "-D warnings"
jobs:
# ── 1. Lint ─────────────────────────────────────────────────────────────
lint:
name: Lint (fmt + clippy)
runs-on: ubuntu-latest
if: github.event_name != 'schedule'
steps:
- uses: actions/checkout@v4
- name: Install Rust stable with fmt + clippy
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Restore cargo cache
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-lint-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-lint-
- name: cargo fmt --check
run: cargo fmt --all -- --check
- name: cargo clippy
run: cargo clippy --features testutils -- -D warnings
# ── 2. Test + Coverage ──────────────────────────────────────────────────
test:
name: Test & Coverage
runs-on: ubuntu-latest
if: github.event_name != 'schedule'
steps:
- uses: actions/checkout@v4
- name: Install Rust stable with llvm-tools
uses: dtolnay/rust-toolchain@stable
with:
components: llvm-tools-preview
- name: Restore cargo cache
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-test-
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- name: Run tests with coverage
run: |
cargo llvm-cov --features testutils \
--lcov --output-path lcov.info \
--summary-only 2>&1 | tee coverage-summary.txt
- name: Generate HTML mutation report
if: always()
run: node scripts/mutation-report.js mutants.out mutants.out/mutation-report.html || true
- name: Upload mutation report
if: always()
uses: actions/upload-artifact@v4
with:
name: workload-governor-wasm-unoptimized
path: target/wasm32v1-none/release/workload_governor.wasm
retention-days: 7
# ── 4. Optimize + Upload Artifact (every main merge) ────────────────────
optimize:
name: Optimize WASM
runs-on: ubuntu-latest
needs: build-wasm
# Run on every push to main AND on every PR (so the artifact is available
# for review). Acceptance criterion: artifact uploaded on every main merge.
if: github.event_name != 'schedule'
steps:
- uses: actions/checkout@v4
- name: Install Rust stable with wasm32v1-none target
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32v1-none
- name: Restore cargo cache
uses: actions/cache@v4
with:
path: |
mutants-report.txt
mutants.out/mutation-report.html
mutants.out/outcomes.json
mutants.out/caught.txt
mutants.out/missed.txt
- name: Optimize WASM
run: |
stellar contract optimize \
--wasm target/wasm32v1-none/release/workload_governor.wasm \
--wasm-out target/wasm32v1-none/release/workload_governor.optimized.wasm
- name: Report WASM size
run: |
SIZE=$(wc -c < target/wasm32v1-none/release/workload_governor.optimized.wasm)
echo "Optimized WASM size: ${SIZE} bytes (limit 65536)"
echo "### 📦 WASM Size" >> "$GITHUB_STEP_SUMMARY"
echo "| Build | Size |" >> "$GITHUB_STEP_SUMMARY"
echo "| --- | --- |" >> "$GITHUB_STEP_SUMMARY"
echo "| Optimized | ${SIZE} bytes |" >> "$GITHUB_STEP_SUMMARY"
[ "$SIZE" -le 65536 ] || (echo "❌ WASM exceeds 64 KB limit" && exit 1)
- name: Upload optimized WASM artifact
uses: actions/upload-artifact@v4
with:
name: workload-governor-wasm-optimized
path: target/wasm32v1-none/release/workload_governor.optimized.wasm
# Permanent retention on main merges; 7 days on PRs
retention-days: ${{ github.ref == 'refs/heads/main' && 90 || 7 }}
# ── 5. Fuzz (nightly schedule only, 10-minute run) ───────────────────────
fuzz:
name: Fuzz (10 min)
runs-on: ubuntu-latest
if: github.event_name == 'schedule'
steps:
- uses: actions/checkout@v4
- name: Install Rust nightly
uses: dtolnay/rust-toolchain@nightly
- name: Restore cargo cache
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-fuzz-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-fuzz-
- name: Install cargo-fuzz
run: cargo install cargo-fuzz --locked
- name: Run fuzz targets (10 minutes each)
run: |
for target in $(cargo fuzz list 2>/dev/null || true); do
echo "▶ Fuzzing target: $target"
cargo fuzz run "$target" -- -max_total_time=600 || true
done
continue-on-error: true
- name: Upload fuzz artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: fuzz-artifacts-${{ github.run_id }}
path: fuzz/artifacts/
if-no-files-found: ignore
retention-days: 30