diff --git a/.github/scripts/list-test-packages.sh b/.github/scripts/list-test-packages.sh new file mode 100755 index 000000000..ce32602e9 --- /dev/null +++ b/.github/scripts/list-test-packages.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# Script to list all workspace packages with their test requirements +# Outputs JSON suitable for GitHub Actions matrix strategy + +set -euo pipefail + +# Packages that require nightly Rust +NIGHTLY_PACKAGES=( + "mina-tree" + "vrf" + "mina-p2p-messages" + "transaction_fuzzer" +) + +# Packages that don't have unit tests or shouldn't be tested +# cli is tested via wallet-tests (end-to-end tests) +SPECIAL_PACKAGES=( + "cli" +) + +# Helper function to check if an element is in an array +contains_element() { + local element="$1" + shift + local array=("$@") + for item in "${array[@]}"; do + if [[ "$item" == "$element" ]]; then + return 0 + fi + done + return 1 +} + +# Get all workspace packages with their features +packages_data=$(cargo metadata --no-deps --format-version 1 2>/dev/null | \ + jq -r '.packages[] | "\(.name)|\(.features | keys | length)"') + +matrix_entries=() + +while IFS='|' read -r package_name feature_count; do + # Skip special packages that have dedicated CI jobs + if contains_element "$package_name" "${SPECIAL_PACKAGES[@]}"; then + continue + fi + + # Determine toolchain + toolchain="stable" + if contains_element "$package_name" "${NIGHTLY_PACKAGES[@]}"; then + toolchain="nightly" + fi + + # Determine if --all-features is needed + all_features="false" + if [[ "$feature_count" -gt 0 ]]; then + all_features="true" + fi + + # Create matrix entry + entry=$(jq -n \ + --arg name "$package_name" \ + --arg toolchain "$toolchain" \ + --arg all_features "$all_features" \ + '{ + package: $name, + toolchain: $toolchain, + all_features: ($all_features == "true") + }') + + matrix_entries+=("$entry") +done <<< "$packages_data" + +# Combine all entries into a JSON array (compact format for GitHub Actions) +if [[ ${#matrix_entries[@]} -eq 0 ]]; then + echo '{"include":[]}' +else + printf '%s\n' "${matrix_entries[@]}" | jq -s -c '{include: .}' +fi diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 58216fafd..47661c4da 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -40,156 +40,6 @@ jobs: - name: Clean cargo cache run: cargo clean - ledger-tests: - timeout-minutes: 20 - runs-on: ubuntu-24.04 - steps: - - name: Git checkout - uses: actions/checkout@v5 - - - name: Setup build dependencies - uses: ./.github/actions/setup-build-deps - - - name: Use shared OCaml setting up steps - uses: ./.github/actions/setup-ocaml - with: - ocaml_version: ${{ env.OCAML_VERSION }} - - - name: Setup Rust - uses: ./.github/actions/setup-rust - with: - toolchain: ${{ env.RUST_NIGHTLY_VERSION }} - cache-prefix: ledger-${{ env.CACHE_VERSION }} - - - name: Download circuits files - uses: ./.github/actions/setup-circuits - - - name: Build ledger tests - run: make build-ledger - - - name: Run ledger tests - run: make test-ledger - - mina-node-native-tests: - timeout-minutes: 30 - runs-on: ubuntu-24.04 - steps: - - name: Git checkout - uses: actions/checkout@v5 - - - name: Setup build dependencies - uses: ./.github/actions/setup-build-deps - - - name: Setup Rust - uses: ./.github/actions/setup-rust - with: - toolchain: ${{ env.RUST_STABLE_VERSION }} - cache-prefix: mina-node-native-${{ env.CACHE_VERSION }} - - - name: Test mina-node-native crate - run: make test-node-native - - p2p-messages-tests: - timeout-minutes: 20 - runs-on: ubuntu-24.04 - steps: - - name: Git checkout - uses: actions/checkout@v5 - - - name: Setup build dependencies - uses: ./.github/actions/setup-build-deps - - - name: Setup Rust - uses: ./.github/actions/setup-rust - with: - toolchain: ${{ env.RUST_NIGHTLY_VERSION }} - cache-prefix: p2p-messages-${{ env.CACHE_VERSION }} - - - name: Download circuits files - uses: ./.github/actions/setup-circuits - - - name: Run mina-p2p-messages - run: make test-p2p-messages - - # TODO: add back when reimplemented - # ledger-32x9-tests: - # runs-on: ubuntu-24.04 - # steps: - # - name: Git checkout - # uses: actions/checkout@v5 - - # - name: Setup build dependencies - # uses: ./.github/actions/setup-build-deps - - # - name: Setup Rust - # uses: ./.github/actions/setup-rust - # with: - # toolchain: nightly - # cache-prefix: ledger-32x9-v0 - - # - name: Download circuits files - # uses: ./.github/actions/setup-circuits - - # - name: Enable 32x9 fields implementation - # run: | - # cargo install sd - # sd '^mina-curves.*$' '' ./Cargo.toml - # sd '^ark-ff = \{ version .*$' '' ./Cargo.toml - # sd -F '# UNCOMMENTED_IN_CI ' '' ./Cargo.toml - # cat ./Cargo.toml - - # - name: Build ledger tests - # run: make build-ledger - - # - name: Run ledger tests - # run: make test-ledger - - vrf-tests: - timeout-minutes: 20 - runs-on: ubuntu-24.04 - steps: - - name: Git checkout - uses: actions/checkout@v5 - - - name: Setup build dependencies - uses: ./.github/actions/setup-build-deps - - - name: Use shared OCaml setting up steps - uses: ./.github/actions/setup-ocaml - with: - ocaml_version: ${{ env.OCAML_VERSION }} - - - name: Setup Rust - uses: ./.github/actions/setup-rust - with: - toolchain: ${{ env.RUST_NIGHTLY_VERSION }} - cache-prefix: vrf-${{ env.CACHE_VERSION }} - - - name: Build vrf tests - run: make build-vrf - - - name: Run vrf tests - run: make test-vrf - - p2p-tests: - timeout-minutes: 15 - runs-on: ubuntu-24.04 - steps: - - name: Git checkout - uses: actions/checkout@v5 - - - name: Setup build dependencies - uses: ./.github/actions/setup-build-deps - - - name: Setup Rust - uses: ./.github/actions/setup-rust - with: - toolchain: ${{ env.RUST_STABLE_VERSION }} - cache-prefix: p2p-${{ env.CACHE_VERSION }} - - - name: Test p2p crate - run: make test-p2p - # Fast builds specifically for test artifacts - no cross-platform matrix build: timeout-minutes: 60 @@ -239,9 +89,32 @@ jobs: path: target/release/mina retention-days: 7 - account-tests: - timeout-minutes: 20 + # Generate matrix of all packages to test + generate-test-matrix: + runs-on: ubuntu-24.04 + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - name: Git checkout + uses: actions/checkout@v5 + + - name: Generate test matrix + id: set-matrix + run: | + MATRIX=$(./.github/scripts/list-test-packages.sh) + echo "matrix=$MATRIX" >> $GITHUB_OUTPUT + echo "Generated matrix:" + echo "$MATRIX" | jq . + + # Test all packages in parallel + package-tests: + needs: generate-test-matrix + timeout-minutes: 30 runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.generate-test-matrix.outputs.matrix) }} + name: unit-integration-tests-${{ matrix.package }} steps: - name: Git checkout uses: actions/checkout@v5 @@ -249,14 +122,23 @@ jobs: - name: Setup build dependencies uses: ./.github/actions/setup-build-deps + - name: Setup OCaml (if needed) + if: matrix.package == 'mina-tree' || matrix.package == 'vrf' + uses: ./.github/actions/setup-ocaml + with: + ocaml_version: ${{ env.OCAML_VERSION }} + + - name: Setup circuits + uses: ./.github/actions/setup-circuits + - name: Setup Rust uses: ./.github/actions/setup-rust with: - toolchain: ${{ env.RUST_STABLE_VERSION }} - cache-prefix: build-${{ env.CACHE_VERSION }} + toolchain: ${{ matrix.toolchain == 'nightly' && env.RUST_NIGHTLY_VERSION || env.RUST_STABLE_VERSION }} + cache-prefix: test-${{ matrix.package }}-${{ env.CACHE_VERSION }} - - name: Run account tests - run: make test-account + - name: Test package + run: make test-package PACKAGE=${{ matrix.package }} ALL_FEATURES=${{ matrix.all_features }} wallet-tests: needs: [build] diff --git a/Makefile b/Makefile index a1c240c09..c145c8241 100644 --- a/Makefile +++ b/Makefile @@ -63,13 +63,6 @@ help: ## Ask for help! build: ## Build the project in debug mode cargo build -.PHONY: build-ledger -build-ledger: download-circuits ## Build the ledger binary and library, requires nightly Rust - @cd ledger && cargo +$(NIGHTLY_RUST_VERSION) build --release --tests - -build-node-native: ## Build the package mina-node-native with all features and tests - @cargo build -p mina-node-native --all-features --release --tests - .PHONY: build-release build-release: ## Build the project in release mode @cargo build --release --package=cli --bin mina @@ -113,10 +106,6 @@ build-tests-webrtc: ## Build tests for WebRTC cp -a $$FILE target/release/tests/webrtc_$$NAME; \ done < tests.tsv -.PHONY: build-vrf -build-vrf: ## Build the VRF package - @cd vrf && cargo +$(NIGHTLY_RUST_VERSION) build --release --tests - .PHONY: build-wasm build-wasm: ## Build WebAssembly node @cd node/web && cargo +${NIGHTLY_RUST_VERSION} build \ @@ -291,27 +280,24 @@ setup-wasm: ## Setup the WebAssembly toolchain, using nightly test: ## Run tests cargo test -.PHONY: test-ledger -test-ledger: build-ledger ## Run ledger tests in release mode, requires nightly Rust - @cd ledger && cargo +$(NIGHTLY_RUST_VERSION) test --release -- -Z unstable-options --report-time - -.PHONY: test-p2p -test-p2p: ## Run P2P tests - cargo test -p p2p --tests --release +.PHONY: test-package +test-package: ## Test a specific package in release mode (use PACKAGE=name, optionally ALL_FEATURES=true) + @if [ -z "$(PACKAGE)" ]; then \ + echo "Error: PACKAGE is required. Usage: make test-package PACKAGE=mina-core [ALL_FEATURES=true]"; \ + exit 1; \ + fi + @if [ "$(ALL_FEATURES)" = "true" ]; then \ + echo "Testing package $(PACKAGE) with --all-features in release mode..."; \ + cargo test -p $(PACKAGE) --all-features --release; \ + else \ + echo "Testing package $(PACKAGE) in release mode..."; \ + cargo test -p $(PACKAGE) --release; \ + fi .PHONY: test-release test-release: ## Run tests in release mode cargo test --release -.PHONY: test-vrf -test-vrf: ## Run VRF tests, requires nightly Rust - @cd vrf && cargo +$(NIGHTLY_RUST_VERSION) test --release -- \ - -Z unstable-options --report-time - -.PHONY: test-account -test-account: ## Run account tests - @cargo test -p mina-node-account - .PHONY: test-wallet test-wallet: ## Run wallet CLI end-to-end tests @echo "Running wallet CLI tests..." @@ -321,33 +307,19 @@ test-wallet: ## Run wallet CLI end-to-end tests done @echo "All wallet tests passed!" -.PHONY: test-p2p-messages -test-p2p-messages: - cargo test -p mina-p2p-messages --tests --release - -.PHONY: test-node-native -test-node-native: build-node-native ## Run the unit/integration tests of the package mina-node-native - cargo test -p mina-node-native --all-features --release --tests - -.PHONY: nextest -nextest: ## Run tests with cargo-nextest for faster execution - @cargo nextest run - -.PHONY: nextest-release -nextest-release: ## Run tests in release mode with cargo-nextest - @cargo nextest run --release - -.PHONY: nextest-p2p -nextest-p2p: ## Run P2P tests with cargo-nextest - @cargo nextest run -p p2p --tests - -.PHONY: nextest-ledger -nextest-ledger: build-ledger ## Run ledger tests with cargo-nextest, requires nightly Rust - @cd ledger && cargo +$(NIGHTLY_RUST_VERSION) nextest run --release - -.PHONY: nextest-vrf -nextest-vrf: ## Run VRF tests with cargo-nextest, requires nightly Rust - @cd vrf && cargo +$(NIGHTLY_RUST_VERSION) nextest run --release +.PHONY: nextest-package +nextest-package: ## Test a specific package with nextest in release mode (use PACKAGE=name, optionally ALL_FEATURES=true) + @if [ -z "$(PACKAGE)" ]; then \ + echo "Error: PACKAGE is required. Usage: make nextest-package PACKAGE=mina-core [ALL_FEATURES=true]"; \ + exit 1; \ + fi + @if [ "$(ALL_FEATURES)" = "true" ]; then \ + echo "Testing package $(PACKAGE) with --all-features using nextest in release mode..."; \ + cargo nextest run -p $(PACKAGE) --all-features --release; \ + else \ + echo "Testing package $(PACKAGE) using nextest in release mode..."; \ + cargo nextest run -p $(PACKAGE) --release; \ + fi # Docker build targets