diff --git a/.ci/ci_check.sh b/.ci/ci_check.sh index 6b2995d20..0422f560c 100755 --- a/.ci/ci_check.sh +++ b/.ci/ci_check.sh @@ -243,6 +243,36 @@ run_integration_round() return 0 } +# map a round id -> (version, outdir, ports, rpc_port, sm, extra) and run it: +# download that one version, build its single 4-node cert-free chain, then run +# one integrationTest pass against it. Splitting the rounds this way lets CI run +# them as independent parallel jobs (one 4-node chain per runner) instead of one +# runner carrying all three chains (12 nodes) through three sequential rounds. +build_and_run_round() +{ + local round="${1}" + local tag outdir ports rpc_port sm extra name + case "${round}" in + pinned-ecdsa) tag="${PINNED_VERSION}"; outdir="nodes_pinned"; ports="30300,20200"; rpc_port=20200; sm="false"; extra=""; ;; + latest-ecdsa) tag="$(get_latest_version)"; outdir="nodes_latest"; ports="30310,20210"; rpc_port=20210; sm="false"; extra=""; ;; + latest-sm) tag="$(get_latest_version)"; outdir="nodes_latest_sm"; ports="30320,20220"; rpc_port=20220; sm="true"; extra="-s"; ;; + *) echo "unknown round '${round}' (want: pinned-ecdsa | latest-ecdsa | latest-sm)"; exit 2 ;; + esac + if ! echo "${tag}" | grep -qE "^v[0-9]+\.[0-9]+\.[0-9]+$"; then + echo "failed to resolve node version for round '${round}', got: '${tag}'" + exit 1 + fi + if [ "${sm}" = "true" ]; then name="sm @ ${tag}"; else name="ecdsa @ ${tag}"; fi + download_build_chain "${tag}" + download_binary "${tag}" + build_chain_one "${tag}" "${outdir}" "${ports}" "${extra}" + run_integration_round "${name}" "${rpc_port}" "${sm}" "${outdir}" +} + +# round selector: a single round id (CI runs one per job, in parallel) or "all" +# (local / fallback: run all three sequentially in this one invocation) +ROUND="${1:-all}" + LOG_INFO "------ check java version ---------" java -version @@ -259,36 +289,23 @@ if [ ! -f "get_gm_account.sh" ];then fi PINNED_VERSION="v3.7.3" -LATEST_VERSION=$(get_latest_version) -if ! echo "${LATEST_VERSION}" | grep -qE "^v[0-9]+\.[0-9]+\.[0-9]+$"; then - echo "failed to resolve the latest FISCO BCOS release tag, got: '${LATEST_VERSION}'" - exit 1 -fi -LOG_INFO "------ node versions: ${PINNED_VERSION} (pinned) + ${LATEST_VERSION} (latest) ---------" - -download_build_chain "${PINNED_VERSION}" -download_binary "${PINNED_VERSION}" -if [ "${LATEST_VERSION}" != "${PINNED_VERSION}" ];then - download_build_chain "${LATEST_VERSION}" - download_binary "${LATEST_VERSION}" -fi - -# three chains, started together on disjoint ports, all with certificate-free rpc -build_chain_one "${PINNED_VERSION}" "nodes_pinned" "30300,20200" -build_chain_one "${LATEST_VERSION}" "nodes_latest" "30310,20210" -build_chain_one "${LATEST_VERSION}" "nodes_latest_sm" "30320,20220" "-s" - -# chain1 is needed right away; chains 2/3 have the whole preceding rounds to -# finish booting, so a slow start there is only logged, not fatal — each round -# re-checks readiness itself -wait_rpc_ready 20200 -wait_rpc_ready 20210 || true -wait_rpc_ready 20220 || true - FAILED_ROUNDS="" -run_integration_round "ecdsa @ ${PINNED_VERSION}" 20200 "false" "nodes_pinned" -run_integration_round "ecdsa @ ${LATEST_VERSION}" 20210 "false" "nodes_latest" -run_integration_round "sm @ ${LATEST_VERSION}" 20220 "true" "nodes_latest_sm" + +case "${ROUND}" in + all) + LOG_INFO "------ running all rounds sequentially (local/fallback mode) ------" + build_and_run_round pinned-ecdsa + build_and_run_round latest-ecdsa + build_and_run_round latest-sm + ;; + pinned-ecdsa|latest-ecdsa|latest-sm) + build_and_run_round "${ROUND}" + ;; + *) + echo "usage: $(basename "$0") [all|pinned-ecdsa|latest-ecdsa|latest-sm]" + exit 2 + ;; +esac if [ -n "${FAILED_ROUNDS}" ]; then echo "integration rounds failed:${FAILED_ROUNDS}" diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index bda4fd6c3..a2b5a6df9 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -14,16 +14,17 @@ env: jobs: build: name: build - # Heavy integration build runs on PRs and releases only; pushes to the main - # branches run just the lightweight 'coverage' job below (to upload a Codecov - # BASE report so PRs can show a coverage delta). + # Windows build (compile + unit tests, no integration). Heavy integration + # tests run in the separate 'integration' job below. Both run on PRs and + # releases only; pushes to the main branches run just the lightweight + # 'coverage' job (to upload a Codecov BASE report so PRs show a coverage delta). if: github.event_name != 'push' runs-on: ${{ matrix.os }} continue-on-error: true strategy: fail-fast: false matrix: - os: [ ubuntu-latest, windows-2025, macos-latest ] + os: [ windows-2025 ] steps: - uses: actions/checkout@v3 with: @@ -35,13 +36,65 @@ jobs: ~/.gradle/caches ~/.gradle/wrapper ~/.m2/repository - ~/.ccache - ~/.fisco key: build-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} restore-keys: | build-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} build-${{ matrix.os }}-${{ github.base_ref }}- build-${{ matrix.os }}- + - name: Set up JDK 1.8.0.382 + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: '8.0.382' + - name: run build test + run: ./gradlew.bat build + + integration: + name: integration + # One integration round per job so the rounds run as independent parallel + # jobs (each builds a single 4-node chain) instead of one runner carrying + # all three chains through three sequential rounds. Same tests, same serial + # per-round execution — only the rounds are parallelized. + # + # Asymmetric matrix: ubuntu runs all three rounds in parallel (Linux runner + # concurrency is ample), while macOS runs only the latest-ecdsa round. + # GitHub-hosted macOS runner slots are a scarce org-wide resource (cap ~5, + # shared across the whole org), so extra macOS legs just queue behind other + # org activity and buy no wall-clock — one macOS smoke round is enough to + # keep the platform covered without hogging those slots. + if: github.event_name != 'push' + runs-on: ${{ matrix.os }} + continue-on-error: true + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + round: pinned-ecdsa + - os: ubuntu-latest + round: latest-ecdsa + - os: ubuntu-latest + round: latest-sm + - os: macos-latest + round: latest-ecdsa + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 5 + - uses: actions/cache@v3 + id: deps_cache + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + ~/.m2/repository + ~/.ccache + ~/.fisco + key: integration-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} + restore-keys: | + integration-${{ matrix.os }}-${{ github.base_ref }}-${{ hashFiles('.github/workflows/workflow.yml') }} + integration-${{ matrix.os }}-${{ github.base_ref }}- + integration-${{ matrix.os }}- - name: install Ubuntu dependencies if: runner.os == 'Linux' run: | @@ -55,12 +108,8 @@ jobs: with: distribution: 'zulu' java-version: '8.0.382' - - name: run build test - if: runner.os == 'Windows' - run: ./gradlew.bat build - name: run integration testing - if: runner.os != 'Windows' - run: /bin/bash .ci/ci_check.sh + run: /bin/bash .ci/ci_check.sh ${{ matrix.round }} coverage: name: coverage diff --git a/AGENTS.md b/AGENTS.md index c4a83b519..b8f2e4965 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -34,18 +34,27 @@ the repo's git pre-commit hook (`copyHooks` task copies from `hooks/`). ### Integration tests require a running chain `./gradlew integrationTest` (EVM/Solidity) **cannot run without a live FISCO BCOS node**. CI -provisions this in `.ci/ci_check.sh`: it starts three local 4-node chains at once with -`build_chain.sh` on disjoint ports — a pinned v3.7.3 ECDSA chain (rpc 20200), an ECDSA chain on the -**latest release** (rpc 20210, tag auto-resolved from the GitHub `releases/latest` redirect), and an -SM-crypto chain on the latest release (rpc 20220). All chains run with **SSL disabled on the RPC -endpoint** (`disable_ssl=true` / `enable_ssl=false` in each node's `[rpc]` config), so the SDK -connects **without certificates** (`enableSsl = "false"` in the rendered -`src/integration-test/resources/config.toml`; `useSMCrypto` toggled per round). `integrationTest` -then runs once per chain. (`./gradlew integrationWasmTest` still exists but is no longer exercised -in CI.) Do not expect these tasks to pass in a bare checkout. - -CI entrypoint is `.github/workflows/workflow.yml` → `.ci/ci_check.sh` (Linux/macOS run the three -integration rounds; Windows runs only `./gradlew.bat build`). +provisions this in `.ci/ci_check.sh`, which takes a **round id** and builds just that round's single +4-node chain with `build_chain.sh`, then runs one `integrationTest` pass against it. The three rounds: +- `pinned-ecdsa` — pinned v3.7.3 ECDSA chain (rpc 20200) +- `latest-ecdsa` — ECDSA chain on the **latest release** (rpc 20210, tag auto-resolved from the GitHub `releases/latest` redirect) +- `latest-sm` — SM-crypto chain on the latest release (rpc 20220) + +Each chain runs with **SSL disabled on the RPC endpoint** (`disable_ssl=true` / `enable_ssl=false` in +each node's `[rpc]` config), so the SDK connects **without certificates** (`enableSsl = "false"` in the +rendered `src/integration-test/resources/config.toml`, single peer; `useSMCrypto` toggled per round). +Running `.ci/ci_check.sh` with **no argument** (or `all`) builds all three chains and runs the rounds +sequentially — the local/fallback path. (`./gradlew integrationWasmTest` still exists but is no longer +exercised in CI.) Do not expect these tasks to pass in a bare checkout. + +CI entrypoint is `.github/workflows/workflow.yml`. The `integration` job runs each round as a separate +**parallel** matrix leg (`.ci/ci_check.sh `), so the chains run on independent runners (one +4-node chain each) instead of one runner carrying all twelve nodes through three sequential rounds. The +matrix is **asymmetric**: `ubuntu-latest` runs all three rounds (`pinned-ecdsa`, `latest-ecdsa`, +`latest-sm`) in parallel, while `macos-latest` runs only `latest-ecdsa` — GitHub-hosted macOS runner +slots are a scarce org-wide resource (cap ~5, shared across the whole org), so extra macOS legs only +queue and buy no wall-clock; one macOS smoke round keeps the platform covered. The `build` job runs +only `./gradlew.bat build` on Windows (compile + unit tests, no integration). ### Native dependency note