chore: bump version to 0.2.1 #40
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: rusd CI | |
| on: | |
| push: | |
| branches: [main, master, develop] | |
| pull_request: | |
| branches: [main, master, develop] | |
| permissions: | |
| contents: read | |
| env: | |
| CARGO_TERM_COLOR: always | |
| RUST_BACKTRACE: 1 | |
| RUSTFLAGS: "-D warnings" | |
| jobs: | |
| # ============================================================================ | |
| # Job 1: Build and Unit Tests | |
| # ============================================================================ | |
| build-and-test: | |
| name: Build & Unit Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| components: clippy, rustfmt | |
| - name: Install protobuf compiler | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y protobuf-compiler libprotobuf-dev | |
| - name: Cache Cargo registry and build | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock', '**/Cargo.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo- | |
| - name: Check formatting | |
| run: cargo fmt -- --check | |
| - name: Run clippy lints | |
| run: cargo clippy --all-targets -- -D warnings | |
| continue-on-error: true # Non-blocking until lint issues are resolved | |
| - name: Build (debug) | |
| run: cargo build --verbose | |
| - name: Build (release) | |
| run: cargo build --release --verbose | |
| - name: Run unit tests | |
| run: cargo test --lib --verbose -- --test-threads=4 | |
| - name: Run doc tests | |
| run: cargo test --doc --verbose | |
| - name: Upload release binary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: rusd-binary | |
| path: target/release/rusd | |
| retention-days: 1 | |
| # ============================================================================ | |
| # Job 2: Integration Tests | |
| # ============================================================================ | |
| integration-tests: | |
| name: Integration Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| needs: build-and-test | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install protobuf compiler | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y protobuf-compiler libprotobuf-dev | |
| - name: Cache Cargo registry and build | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock', '**/Cargo.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo- | |
| - name: Run integration tests | |
| run: cargo test --test integration_test --verbose -- --test-threads=1 | |
| continue-on-error: true # Integration tests require a running server | |
| # ============================================================================ | |
| # Job 3: Single-Node etcdctl Validation | |
| # ============================================================================ | |
| single-node-validation: | |
| name: Single-Node etcdctl Validation | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| needs: build-and-test | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Download rusd binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: rusd-binary | |
| path: ./target/release/ | |
| - name: Make binary executable | |
| run: chmod +x ./target/release/rusd | |
| - name: Install etcdctl | |
| run: | | |
| ETCD_VER=v3.5.17 | |
| curl -L https://github.com/etcd-io/etcd/releases/download/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd.tar.gz | |
| mkdir -p /tmp/etcd | |
| tar xzf /tmp/etcd.tar.gz -C /tmp/etcd --strip-components=1 | |
| sudo cp /tmp/etcd/etcdctl /usr/local/bin/ | |
| etcdctl version | |
| - name: Start rusd server (single-node) | |
| run: | | |
| mkdir -p /tmp/rusd-single-node | |
| ./target/release/rusd \ | |
| --name test-node \ | |
| --data-dir /tmp/rusd-single-node \ | |
| --listen-client-urls "http://0.0.0.0:2379" \ | |
| --listen-peer-urls "http://0.0.0.0:2380" \ | |
| --advertise-client-urls "http://127.0.0.1:2379" \ | |
| --initial-advertise-peer-urls "http://127.0.0.1:2380" \ | |
| --initial-cluster "test-node=http://127.0.0.1:2380" \ | |
| --initial-cluster-state new \ | |
| --log-level info \ | |
| > /tmp/rusd-single.log 2>&1 & | |
| RUSD_PID=$! | |
| echo "RUSD_PID=$RUSD_PID" >> $GITHUB_ENV | |
| echo "Started rusd with PID $RUSD_PID" | |
| - name: Wait for rusd to be ready | |
| run: | | |
| echo "Waiting for rusd to start..." | |
| for i in $(seq 1 60); do | |
| if etcdctl --endpoints=http://127.0.0.1:2379 endpoint health 2>/dev/null; then | |
| echo "rusd is ready after ${i}s" | |
| break | |
| fi | |
| if [ "$i" -eq 60 ]; then | |
| echo "rusd failed to start. Server log:" | |
| cat /tmp/rusd-single.log || true | |
| exit 1 | |
| fi | |
| sleep 1 | |
| done | |
| - name: Run etcdctl validation tests | |
| run: | | |
| ENDPOINT="http://127.0.0.1:2379" | |
| PASS=0 | |
| FAIL=0 | |
| TOTAL=0 | |
| run_test() { | |
| local name="$1" | |
| local cmd="$2" | |
| TOTAL=$((TOTAL + 1)) | |
| echo "--- Test: $name ---" | |
| if eval "$cmd"; then | |
| echo "PASS: $name" | |
| PASS=$((PASS + 1)) | |
| else | |
| echo "FAIL: $name" | |
| FAIL=$((FAIL + 1)) | |
| fi | |
| } | |
| # Test: Put and Get | |
| run_test "Put/Get" ' | |
| etcdctl --endpoints=$ENDPOINT put /ci/key1 "value1" && | |
| RESULT=$(etcdctl --endpoints=$ENDPOINT get /ci/key1 --print-value-only) && | |
| [ "$RESULT" = "value1" ] | |
| ' | |
| # Test: Delete | |
| run_test "Delete" ' | |
| etcdctl --endpoints=$ENDPOINT put /ci/delkey "todelete" && | |
| etcdctl --endpoints=$ENDPOINT del /ci/delkey && | |
| RESULT=$(etcdctl --endpoints=$ENDPOINT get /ci/delkey --print-value-only) && | |
| [ -z "$RESULT" ] | |
| ' | |
| # Test: Range scan with prefix | |
| run_test "Range prefix scan" ' | |
| etcdctl --endpoints=$ENDPOINT put /ci/range/a "1" && | |
| etcdctl --endpoints=$ENDPOINT put /ci/range/b "2" && | |
| etcdctl --endpoints=$ENDPOINT put /ci/range/c "3" && | |
| COUNT=$(etcdctl --endpoints=$ENDPOINT get /ci/range/ --prefix --print-value-only | wc -l | tr -d " ") && | |
| [ "$COUNT" -ge 3 ] | |
| ' | |
| # Test: Member list | |
| run_test "Member list" ' | |
| etcdctl --endpoints=$ENDPOINT member list | |
| ' | |
| # Test: Endpoint status | |
| run_test "Endpoint status" ' | |
| etcdctl --endpoints=$ENDPOINT endpoint status | |
| ' | |
| # Test: Endpoint health | |
| run_test "Endpoint health" ' | |
| etcdctl --endpoints=$ENDPOINT endpoint health | |
| ' | |
| # Test: Lease grant | |
| run_test "Lease grant" ' | |
| etcdctl --endpoints=$ENDPOINT lease grant 300 | |
| ' | |
| # Test: Multiple rapid puts | |
| run_test "Rapid sequential puts (50 keys)" ' | |
| for i in $(seq 1 50); do | |
| etcdctl --endpoints=$ENDPOINT put "/ci/rapid/key$i" "val$i" > /dev/null | |
| done | |
| COUNT=$(etcdctl --endpoints=$ENDPOINT get /ci/rapid/ --prefix --count-only 2>/dev/null | grep -o "[0-9]*" | head -1) | |
| [ "$COUNT" -ge 50 ] | |
| ' | |
| # Test: Overwrite key | |
| run_test "Key overwrite" ' | |
| etcdctl --endpoints=$ENDPOINT put /ci/overwrite "v1" && | |
| etcdctl --endpoints=$ENDPOINT put /ci/overwrite "v2" && | |
| RESULT=$(etcdctl --endpoints=$ENDPOINT get /ci/overwrite --print-value-only) && | |
| [ "$RESULT" = "v2" ] | |
| ' | |
| # Test: Empty value | |
| run_test "Empty value" ' | |
| etcdctl --endpoints=$ENDPOINT put /ci/empty "" | |
| ' | |
| echo "" | |
| echo "======================================" | |
| echo " Single-Node Validation Results" | |
| echo "======================================" | |
| echo "Passed: $PASS / $TOTAL" | |
| echo "Failed: $FAIL / $TOTAL" | |
| echo "======================================" | |
| # Save results for artifact | |
| cat > /tmp/single-node-results.json <<EOF | |
| { | |
| "total": $TOTAL, | |
| "passed": $PASS, | |
| "failed": $FAIL, | |
| "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)" | |
| } | |
| EOF | |
| if [ $FAIL -gt 2 ]; then | |
| echo "Too many failures ($FAIL). Failing CI." | |
| exit 1 | |
| fi | |
| - name: Stop rusd server | |
| if: always() | |
| run: | | |
| if [ -n "$RUSD_PID" ]; then | |
| kill "$RUSD_PID" 2>/dev/null || true | |
| fi | |
| - name: Upload server log | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: single-node-server-log | |
| path: /tmp/rusd-single.log | |
| retention-days: 7 | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: single-node-results | |
| path: /tmp/single-node-results.json | |
| retention-days: 7 | |
| # ============================================================================ | |
| # Job 4: TLS Validation | |
| # ============================================================================ | |
| tls-validation: | |
| name: TLS etcdctl Validation | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| needs: build-and-test | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Download rusd binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: rusd-binary | |
| path: ./target/release/ | |
| - name: Make binary executable | |
| run: chmod +x ./target/release/rusd | |
| - name: Install etcdctl | |
| run: | | |
| ETCD_VER=v3.5.17 | |
| curl -L https://github.com/etcd-io/etcd/releases/download/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd.tar.gz | |
| mkdir -p /tmp/etcd | |
| tar xzf /tmp/etcd.tar.gz -C /tmp/etcd --strip-components=1 | |
| sudo cp /tmp/etcd/etcdctl /usr/local/bin/ | |
| etcdctl version | |
| - name: Run TLS validation tests | |
| run: | | |
| chmod +x scripts/tls-test.sh | |
| ./scripts/tls-test.sh | |
| - name: Upload TLS test log | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: tls-test-log | |
| path: /tmp/rusd-tls-test.log | |
| retention-days: 7 | |
| - name: Upload TLS test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: tls-test-results | |
| path: /tmp/tls-test-results.json | |
| retention-days: 7 | |
| # ============================================================================ | |
| # Job 5: Multi-Node Cluster Validation | |
| # ============================================================================ | |
| multi-node-validation: | |
| name: Multi-Node Cluster Validation | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| needs: build-and-test | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Download rusd binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: rusd-binary | |
| path: ./target/release/ | |
| - name: Make binary executable | |
| run: chmod +x ./target/release/rusd | |
| - name: Install etcdctl | |
| run: | | |
| ETCD_VER=v3.5.17 | |
| curl -L https://github.com/etcd-io/etcd/releases/download/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd.tar.gz | |
| mkdir -p /tmp/etcd | |
| tar xzf /tmp/etcd.tar.gz -C /tmp/etcd --strip-components=1 | |
| sudo cp /tmp/etcd/etcdctl /usr/local/bin/ | |
| etcdctl version | |
| - name: Run multi-node test script | |
| run: | | |
| chmod +x scripts/multi-node-test.sh | |
| ./scripts/multi-node-test.sh | |
| - name: Upload multi-node logs | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: multi-node-logs | |
| path: /tmp/rusd-test/*.log | |
| retention-days: 7 | |
| # ============================================================================ | |
| # Job 6: Benchmarks | |
| # ============================================================================ | |
| benchmarks: | |
| name: Benchmarks | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| needs: build-and-test | |
| # Only run benchmarks on pushes to main, not on every PR | |
| if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Install Rust toolchain | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install protobuf compiler | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y protobuf-compiler libprotobuf-dev | |
| - name: Cache Cargo registry and build | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry | |
| ~/.cargo/git | |
| target | |
| key: ${{ runner.os }}-cargo-bench-${{ hashFiles('**/Cargo.lock', '**/Cargo.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cargo-bench- | |
| ${{ runner.os }}-cargo- | |
| - name: Run criterion benchmarks | |
| run: | | |
| cargo bench --bench rusd_bench -- --output-format=bencher 2>&1 | tee /tmp/benchmark-output.txt | |
| continue-on-error: true # Benchmarks should not block CI | |
| - name: Generate benchmark summary | |
| if: always() | |
| run: | | |
| echo "# Benchmark Results" > /tmp/benchmark-report.md | |
| echo "" >> /tmp/benchmark-report.md | |
| echo "Run: $(date -u +%Y-%m-%dT%H:%M:%SZ)" >> /tmp/benchmark-report.md | |
| echo "Commit: ${{ github.sha }}" >> /tmp/benchmark-report.md | |
| echo "" >> /tmp/benchmark-report.md | |
| echo '```' >> /tmp/benchmark-report.md | |
| cat /tmp/benchmark-output.txt >> /tmp/benchmark-report.md 2>/dev/null || echo "No benchmark output available" >> /tmp/benchmark-report.md | |
| echo '```' >> /tmp/benchmark-report.md | |
| - name: Upload benchmark results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: benchmark-results | |
| path: | | |
| /tmp/benchmark-output.txt | |
| /tmp/benchmark-report.md | |
| target/criterion/ | |
| retention-days: 30 | |
| # ============================================================================ | |
| # Job 7: Docker Build (validates Dockerfile) | |
| # ============================================================================ | |
| docker-build: | |
| name: Docker Build | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| # Only build Docker on pushes to main | |
| if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Build Docker image | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: . | |
| push: false | |
| tags: rusd:ci-${{ github.sha }} | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| # ============================================================================ | |
| # Job 8: Kind Cluster K8s Validation | |
| # ============================================================================ | |
| k8s-validation: | |
| name: Kind Cluster K8s Validation | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| needs: build-and-test | |
| # Heavyweight test: only on pushes to main, not on every PR | |
| if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master') | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Download rusd binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: rusd-binary | |
| path: ./target/release/ | |
| - name: Make binary executable | |
| run: chmod +x ./target/release/rusd | |
| - name: Install etcdctl | |
| run: | | |
| ETCD_VER=v3.5.17 | |
| curl -L https://github.com/etcd-io/etcd/releases/download/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd.tar.gz | |
| mkdir -p /tmp/etcd | |
| tar xzf /tmp/etcd.tar.gz -C /tmp/etcd --strip-components=1 | |
| sudo cp /tmp/etcd/etcdctl /usr/local/bin/ | |
| etcdctl version | |
| - name: Install Kind | |
| run: | | |
| curl -Lo /tmp/kind https://kind.sigs.k8s.io/dl/v0.24.0/kind-linux-amd64 | |
| chmod +x /tmp/kind | |
| sudo mv /tmp/kind /usr/local/bin/kind | |
| kind version | |
| - name: Install kubectl | |
| run: | | |
| KUBECTL_VER=$(curl -L -s --max-time 10 https://dl.k8s.io/release/stable.txt || echo "v1.31.4") | |
| curl -LO "https://dl.k8s.io/release/${KUBECTL_VER}/bin/linux/amd64/kubectl" | |
| chmod +x kubectl | |
| sudo mv kubectl /usr/local/bin/ | |
| kubectl version --client | |
| - name: Run K8s integration tests | |
| run: | | |
| chmod +x scripts/k8s-test.sh | |
| ./scripts/k8s-test.sh | |
| # ============================================================================ | |
| # Job 9: etcd E2E Compatibility Tests | |
| # ============================================================================ | |
| etcd-e2e-compat: | |
| name: etcd E2E Compatibility | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| needs: build-and-test | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Download rusd binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: rusd-binary | |
| path: ./target/release/ | |
| - name: Make binary executable | |
| run: chmod +x ./target/release/rusd | |
| - name: Verify etcd-compatible version output | |
| run: | | |
| echo "=== rusd --version ===" | |
| ./target/release/rusd --version | |
| ./target/release/rusd --version 2>&1 | grep -q "etcd Version:" || { | |
| echo "ERROR: rusd does not output etcd-compatible version string" | |
| exit 1 | |
| } | |
| echo "Version output OK" | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.22' | |
| - name: Clone etcd (shallow) | |
| run: | | |
| git clone --depth 1 --branch v3.5.17 \ | |
| https://github.com/etcd-io/etcd.git /tmp/etcd-src | |
| - name: Build etcdctl and etcdutl (separate Go modules) | |
| run: | | |
| # etcd v3.5.x is a multi-module repo. etcdctl and etcdutl | |
| # have their own go.mod — must build from their directories. | |
| # Place binaries in <etcd-repo>/bin/ (framework default path). | |
| mkdir -p /tmp/etcd-src/bin | |
| cd /tmp/etcd-src/etcdctl && go build -o ../bin/etcdctl . | |
| cd /tmp/etcd-src/etcdutl && go build -o ../bin/etcdutl . | |
| echo "Built etcdctl and etcdutl" | |
| - name: Symlink rusd as etcd in etcd repo bin/ | |
| run: | | |
| ln -sf "$(pwd)/target/release/rusd" /tmp/etcd-src/bin/etcd | |
| echo "Symlinked rusd as etcd" | |
| /tmp/etcd-src/bin/etcd --version | |
| /tmp/etcd-src/bin/etcdctl version | |
| - name: "Tier 1: Smoke — KV Put/Get NoTLS" | |
| run: | | |
| cd /tmp/etcd-src/tests | |
| export PATH="/tmp/etcd-src/bin:$PATH" | |
| go test ./e2e/... \ | |
| -run "TestCtlV3PutNoTLS|TestCtlV3GetNoTLS" \ | |
| -v -timeout 5m -count=1 2>&1 | tee /tmp/tier1.log || true | |
| echo "" | |
| echo "=== Tier 1 Results ===" | |
| grep -c "^--- PASS:" /tmp/tier1.log || echo "0 passed" | |
| grep -c "^--- FAIL:" /tmp/tier1.log || echo "0 failed" | |
| - name: "Tier 2: Core KV Operations" | |
| run: | | |
| cd /tmp/etcd-src/tests | |
| export PATH="/tmp/etcd-src/bin:$PATH" | |
| go test ./e2e/... \ | |
| -run "TestCtlV3Put|TestCtlV3Get|TestCtlV3Del" \ | |
| -v -timeout 10m -count=1 2>&1 | tee /tmp/tier2.log || true | |
| echo "" | |
| echo "=== Tier 2 Results ===" | |
| grep -c "^--- PASS:" /tmp/tier2.log || echo "0 passed" | |
| grep -c "^--- FAIL:" /tmp/tier2.log || echo "0 failed" | |
| - name: "Tier 3: Watch + Lease + Auth" | |
| run: | | |
| cd /tmp/etcd-src/tests | |
| export PATH="/tmp/etcd-src/bin:$PATH" | |
| go test ./e2e/... \ | |
| -run "TestCtlV3Watch|TestCtlV3Lease|TestCtlV3Auth" \ | |
| -v -timeout 15m -count=1 2>&1 | tee /tmp/tier3.log || true | |
| echo "" | |
| echo "=== Tier 3 Results ===" | |
| grep -c "^--- PASS:" /tmp/tier3.log || echo "0 passed" | |
| grep -c "^--- FAIL:" /tmp/tier3.log || echo "0 failed" | |
| - name: Generate compatibility report | |
| if: always() | |
| run: | | |
| echo "╔════════════════════════════════════════════════════════════╗" | |
| echo "║ etcd E2E Compatibility Summary ║" | |
| echo "╚════════════════════════════════════════════════════════════╝" | |
| echo "" | |
| TOTAL_PASS=0 | |
| TOTAL_FAIL=0 | |
| for tier in 1 2 3; do | |
| LOG="/tmp/tier${tier}.log" | |
| if [[ -f "$LOG" ]]; then | |
| P=$(grep -c "^--- PASS:" "$LOG" 2>/dev/null || true) | |
| F=$(grep -c "^--- FAIL:" "$LOG" 2>/dev/null || true) | |
| P=${P:-0} | |
| F=${F:-0} | |
| TOTAL_PASS=$((TOTAL_PASS + P)) | |
| TOTAL_FAIL=$((TOTAL_FAIL + F)) | |
| echo " Tier $tier: $P passed, $F failed" | |
| fi | |
| done | |
| echo "" | |
| echo " Total: $TOTAL_PASS passed, $TOTAL_FAIL failed" | |
| echo "" | |
| # Generate JSON report | |
| cat > /tmp/e2e-compat-report.json <<EOF | |
| { | |
| "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)", | |
| "rusd_version": "$(./target/release/rusd --version 2>&1 | head -1)", | |
| "etcd_test_suite": "v3.5.17", | |
| "total_passed": $TOTAL_PASS, | |
| "total_failed": $TOTAL_FAIL | |
| } | |
| EOF | |
| - name: Upload tier logs | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: etcd-e2e-compat-logs | |
| path: /tmp/tier*.log | |
| retention-days: 14 | |
| - name: Upload compatibility report | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: etcd-e2e-compat-report | |
| path: /tmp/e2e-compat-report.json | |
| retention-days: 30 |