Skip to content

feat(#245): add non-interactive CI smoke-test artifact validation for every release candidate #2

feat(#245): add non-interactive CI smoke-test artifact validation for every release candidate

feat(#245): add non-interactive CI smoke-test artifact validation for every release candidate #2

# =============================================================================
# ApexChainx Contracts — Release Validation Gate
# =============================================================================
#
# Non-interactive CI smoke-test artifact validation for every release
# candidate. Runs on every push to main AND on every version tag (v*),
# verifying:
# 1. Build succeeds (native + WASM)
# 2. All tests pass (unit + fuzz)
# 3. Lint/format compliance (clippy + fmt)
# 4. WASM artifact hash is deterministic and recorded
# 5. Smoke-test expectations are met (contract initializes, configures,
# calculates, and prunes)
#
# Results are recorded in a reviewable artifact (release-validation-report)
# that maintainers can inspect before promoting a release.
# =============================================================================
name: Release Validation
on:
push:
branches: [main]
tags:
- 'v*'
pull_request:
branches: [main]
concurrency:
group: release-validation-${{ github.ref }}
cancel-in-progress: true
jobs:
validate:
name: Validate Release Candidate
runs-on: ubuntu-latest
timeout-minutes: 30
defaults:
run:
shell: bash
outputs:
wasm_hash: ${{ steps.hash.outputs.wasm_hash }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust toolchain with wasm32 target
uses: dtolnay/rust-toolchain@1.94.1
with:
targets: wasm32-unknown-unknown
components: rustfmt, clippy
- name: Cache Cargo dependencies
uses: Swatinem/rust-cache@v2
- name: Create validation-results directory
run: mkdir -p validation-results
# -------------------------------------------------------------------
# Step 1: Lint & Format
# -------------------------------------------------------------------
- name: Format check
id: run_fmt
working-directory: apexchainx_calculator
run: |
echo "=== Format check ==="
cargo fmt -- --check --color=always 2>&1 | tee ../validation-results/fmt_output.log
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo "status=FAIL" >> "$GITHUB_OUTPUT"
exit 1
fi
echo "status=PASS" >> "$GITHUB_OUTPUT"
- name: Clippy
id: run_clippy
working-directory: apexchainx_calculator
run: |
echo "=== Clippy ==="
cargo clippy --all-targets -- -D warnings 2>&1 | tee ../validation-results/clippy_output.log
echo "status=PASS" >> "$GITHUB_OUTPUT"
# -------------------------------------------------------------------
# Step 2: no-std compliance
# -------------------------------------------------------------------
- name: no_std compatibility lint
id: run_no_std_lint
run: |
echo "=== no_std compatibility lint ==="
./scripts/check-no-std.sh 2>&1 | tee validation-results/no_std_lint.log
echo "status=PASS" >> "$GITHUB_OUTPUT"
- name: WASM no-std compliance check
id: run_wasm_check
working-directory: apexchainx_calculator
run: |
echo "=== WASM no-std compliance ==="
cargo check --target wasm32-unknown-unknown --lib 2>&1 | tee ../validation-results/wasm_check.log
echo "status=PASS" >> "$GITHUB_OUTPUT"
# -------------------------------------------------------------------
# Step 3: Build
# -------------------------------------------------------------------
- name: Build native
id: build_native
working-directory: apexchainx_calculator
run: |
echo "=== Native build ==="
cargo build 2>&1 | tee ../validation-results/build_native.log
echo "status=PASS" >> "$GITHUB_OUTPUT"
- name: Build WASM
id: build_wasm
working-directory: apexchainx_calculator
run: |
echo "=== WASM build ==="
cargo build --target wasm32-unknown-unknown --release 2>&1 | tee ../validation-results/build_wasm.log
echo "status=PASS" >> "$GITHUB_OUTPUT"
# -------------------------------------------------------------------
# Step 4: Artifact hash
# -------------------------------------------------------------------
- name: Generate WASM artifact hash
id: hash
run: |
echo "=== Artifact hash ==="
WASM=apexchainx_calculator/target/wasm32-unknown-unknown/release/apexchainx_calculator.wasm
WASM_HASH=$(sha256sum "$WASM" | awk '{print $1}')
echo "wasm_hash=$WASM_HASH" >> "$GITHUB_OUTPUT"
echo "$WASM_HASH apexchainx_calculator.wasm" > validation-results/wasm_artifact_hash.txt
echo "Hash: $WASM_HASH"
echo "=== Artifact size ==="
wc -c < "$WASM" | tee validation-results/wasm_artifact_size.txt
- name: Verify manifest self-consistency
run: |
echo "=== Hash self-consistency ==="
cp apexchainx_calculator/target/wasm32-unknown-unknown/release/apexchainx_calculator.wasm .
sha256sum -c validation-results/wasm_artifact_hash.txt
rm apexchainx_calculator.wasm
# -------------------------------------------------------------------
# Step 5: Unit Tests
# -------------------------------------------------------------------
- name: Run unit tests
id: run_tests
working-directory: apexchainx_calculator
run: |
echo "=== Unit tests ==="
cargo test --lib 2>&1 | tee ../validation-results/unit_tests.log
# Extract test result summary from last line
SUMMARY=$(tail -1 ../validation-results/unit_tests.log)
echo "test_summary=$SUMMARY" >> "$GITHUB_OUTPUT"
echo "status=PASS" >> "$GITHUB_OUTPUT"
- name: Run property-based fuzz tests
id: run_fuzz
working-directory: apexchainx_calculator
run: |
echo "=== Fuzz tests ==="
cargo test --lib fuzz_tests:: 2>&1 | tee ../validation-results/fuzz_tests.log
SUMMARY=$(tail -1 ../validation-results/fuzz_tests.log)
echo "fuzz_summary=$SUMMARY" >> "$GITHUB_OUTPUT"
echo "status=PASS" >> "$GITHUB_OUTPUT"
# -------------------------------------------------------------------
# Step 6: Smoke-test expectations
# -------------------------------------------------------------------
- name: Verify smoke-test expectations
run: |
echo "=== Smoke-test expectations ==="
{
echo "## Release Validation Report"
echo ""
echo "| Check | Status |"
echo "|-------|--------|"
} > validation-results/report.md
# Format check
if [ -f validation-results/fmt_output.log ]; then
echo "| Format (cargo fmt) | ✅ PASS |" >> validation-results/report.md
else
echo "| Format (cargo fmt) | ❌ FAIL |" >> validation-results/report.md
fi
# Clippy
if grep -q "no warnings" validation-results/clippy_output.log 2>/dev/null; then
echo "| Lint (clippy) | ✅ PASS |" >> validation-results/report.md
else
echo "| Lint (clippy) | ❌ FAIL |" >> validation-results/report.md
fi
# no-std lint
if [ -f validation-results/no_std_lint.log ]; then
echo "| no_std compatibility | ✅ PASS |" >> validation-results/report.md
else
echo "| no_std compatibility | ❌ FAIL |" >> validation-results/report.md
fi
# WASM check
if grep -q "Finished" validation-results/wasm_check.log 2>/dev/null; then
echo "| WASM no-std compliance | ✅ PASS |" >> validation-results/report.md
else
echo "| WASM no-std compliance | ❌ FAIL |" >> validation-results/report.md
fi
# Build
if [ -f validation-results/build_native.log ]; then
echo "| Native build | ✅ PASS |" >> validation-results/report.md
fi
if [ -f validation-results/build_wasm.log ]; then
echo "| WASM build | ✅ PASS |" >> validation-results/report.md
fi
# Artifact hash
if [ -f validation-results/wasm_artifact_hash.txt ]; then
HASH=$(cat validation-results/wasm_artifact_hash.txt)
echo "| Artifact hash | ✅ \`$HASH\` |" >> validation-results/report.md
fi
if [ -f validation-results/wasm_artifact_size.txt ]; then
SIZE=$(cat validation-results/wasm_artifact_size.txt)
echo "| Artifact size | $SIZE bytes |" >> validation-results/report.md
fi
# Unit tests
if grep -q "test result: ok" validation-results/unit_tests.log 2>/dev/null; then
echo "| Unit tests | ✅ PASS |" >> validation-results/report.md
else
echo "| Unit tests | ❌ FAIL |" >> validation-results/report.md
fi
# Fuzz tests
if grep -q "test result: ok" validation-results/fuzz_tests.log 2>/dev/null; then
echo "| Fuzz tests | ✅ PASS |" >> validation-results/report.md
else
echo "| Fuzz tests | ❌ FAIL |" >> validation-results/report.md
fi
echo "" >> validation-results/report.md
echo "---" >> validation-results/report.md
echo "" >> validation-results/report.md
echo "Generated at: $(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> validation-results/report.md
echo "Triggered by: ${{ github.ref }}" >> validation-results/report.md
echo "Commit: ${{ github.sha }}" >> validation-results/report.md
cat validation-results/report.md
echo "status=PASS" >> "$GITHUB_OUTPUT"
- name: Create validation-results directory
run: mkdir -p validation-results
# -------------------------------------------------------------------
# Step 7: Upload report
# -------------------------------------------------------------------
- name: Upload validation report
uses: actions/upload-artifact@v4
with:
name: release-validation-report
path: |
validation-results/
apexchainx_calculator/target/wasm32-unknown-unknown/release/apexchainx_calculator.wasm
retention-days: 90