diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e0d8f66 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,127 @@ +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