name: CI on: push: branches: [main, master] pull_request: env: CARGO_TERM_COLOR: always # Pin the toolchain to the declared MSRV so CI matches production. RUST_TOOLCHAIN: 1.90.0 GO_VERSION: "1.25.0" jobs: rust: name: Rust (fmt / clippy / test / build) runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@stable with: toolchain: ${{ env.RUST_TOOLCHAIN }} components: rustfmt, clippy - name: Cache Cargo registry and build uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo- - name: Format check run: cargo fmt --check - name: Test run: cargo test --locked - name: Clippy run: cargo clippy --locked --all-targets -- -D warnings - name: Release build run: cargo build --locked --release - name: Upload release binary uses: actions/upload-artifact@v4 with: name: balance-server-release path: target/release/balance-server if-no-files-found: error go: name: Go (test / vet / build) runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Install Go uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} - name: Cache Go modules uses: actions/cache@v4 with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go- - name: Test run: go test ./... - name: Vet run: go vet ./... - name: Build run: go build ./... compatibility: name: Go ↔ Rust differential + SQLite takeover runs-on: ubuntu-latest needs: [rust, go] steps: - name: Checkout uses: actions/checkout@v4 - name: Install Rust uses: dtolnay/rust-toolchain@stable with: toolchain: ${{ env.RUST_TOOLCHAIN }} - name: Install Go uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} - name: Install Python uses: actions/setup-python@v5 with: python-version: "3.12" - name: Cache Cargo registry and build uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo- - name: Build Rust (debug) and Go reference run: | cargo build --locked go build -o target/integration/go-server ./cmd/balance-server - name: Run differential compatibility scenarios run: python3 tools/compatibility.py --rust-binary target/debug/balance-server