From e519ba7f86730f1b56638ec31de57dbd25b686af Mon Sep 17 00:00:00 2001 From: x3c41a Date: Fri, 8 May 2026 09:07:39 +0200 Subject: [PATCH 1/8] ci: prototype bulletin-polkadot in integration-test matrix Builds the Fellows bulletin-polkadot runtime out-of-tree (default tracks PR polkadot-fellows/runtimes#1170) and runs it on the existing zombienet flow. Configurable via FELLOWS_RUNTIMES_REPO/REF env vars. The Fellows runtime only allows Root or sibling People XCM as Authorizer, so JS/SDK tests that rely on signed authorize_account from TestAccounts are gated behind a new `experimental` matrix flag and skipped for this entry. chain-up + chopsticks compatibility still run, with continue-on-error so prototype breakage does not block PRs. Closes #507 --- .github/workflows/integration-test.yml | 17 ++++++ .gitignore | 1 + examples/justfile | 17 +++++- scripts/create_bulletin_polkadot_spec.sh | 59 +++++++++++++++++++++ scripts/runtimes-matrix.json | 12 +++++ zombienet/bulletin-polkadot-local.toml | 67 ++++++++++++++++++++++++ 6 files changed, 172 insertions(+), 1 deletion(-) create mode 100755 scripts/create_bulletin_polkadot_spec.sh create mode 100644 zombienet/bulletin-polkadot-local.toml diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 3923933f1..80aef488d 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -188,6 +188,7 @@ jobs: - name: Start services working-directory: examples + continue-on-error: ${{ matrix.runtime.experimental == true }} env: RUNTIME_PACKAGE: ${{ matrix.runtime.package }} run: | @@ -196,44 +197,59 @@ jobs: echo "RUNTIME_PACKAGE=${RUNTIME_PACKAGE}" >> "$GITHUB_ENV" just KUBO_VERSION="${KUBO_VERSION}" start-services "$TEST_DIR" "$RUNTIME_PACKAGE" "kubo-native" + # The remaining tests rely on signed `authorize_account` (TestAccounts / + # Sudo), which the bulletin-polkadot Fellows runtime does not expose — + # only Root and XCM from People can authorize. Skip them here until a + # local authorization path lands, but keep `Test chopsticks compatibility` + # in scope as a chain-up sanity check. - name: Test authorize-and-store ws + if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just run-test-authorize-and-store "$TEST_DIR" "$RUNTIME_PACKAGE" "ws" - name: Test authorize-and-store smoldot + if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just run-test-authorize-and-store "$TEST_DIR" "$RUNTIME_PACKAGE" "smoldot" - name: Test store-chunked-data + if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just run-test-store-chunked-data "$TEST_DIR" - name: Test native-ipfs-dag-pb-chunked-data + if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just run-test-native-ipfs-dag-pb-chunked-data "$TEST_DIR" - name: Test store-big-data + if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just run-test-store-big-data "$TEST_DIR" "big32" - name: Test authorize-preimage-and-store + if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just run-test-authorize-preimage-and-store "$TEST_DIR" - name: Test chopsticks compatibility working-directory: examples + continue-on-error: ${{ matrix.runtime.experimental == true }} run: just run-test-chopsticks "ws://127.0.0.1:10000" # SDK Client Tests - name: Test Rust SDK + if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just test-rust-sdk "${{ env.TEST_DIR }}" "$RUNTIME_PACKAGE" - name: Test TypeScript SDK + if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just test-ts-sdk "${{ env.TEST_DIR }}" - name: Test TypeScript SDK (vitest integration) + if: ${{ !matrix.runtime.experimental }} working-directory: examples # TODO: https://github.com/paritytech/polkadot-bulletin-chain/issues/443 # Flaky chunked-store tests hit the per-tx timeout under CI load. @@ -243,6 +259,7 @@ jobs: run: just test-ts-sdk-vitest - name: Run console-ui tests + if: ${{ !matrix.runtime.experimental }} working-directory: console-ui run: just test diff --git a/.gitignore b/.gitignore index 750440eb4..a3b7e743a 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ console-ui/playwright/.cache/ # Specs for zombienet (need to be fresh) zombienet/bulletin-westend-spec.json zombienet/bulletin-paseo-spec.json +zombienet/bulletin-polkadot-spec.json diff --git a/examples/justfile b/examples/justfile index b3a952a57..85044931b 100644 --- a/examples/justfile +++ b/examples/justfile @@ -157,6 +157,9 @@ bulletin-parachain-zombienet-start test_dir runtime="bulletin-westend-runtime": elif [ "{{ runtime }}" = "bulletin-paseo-runtime" ]; then SPEC_SCRIPT="create_bulletin_paseo_spec.sh" ZOMBIENET_TOML="zombienet/bulletin-paseo-local.toml" + elif [ "{{ runtime }}" = "bulletin-polkadot-runtime" ]; then + SPEC_SCRIPT="create_bulletin_polkadot_spec.sh" + ZOMBIENET_TOML="zombienet/bulletin-polkadot-local.toml" else echo "❌ Unhandled runtime: {{ runtime }}" exit 1 @@ -227,6 +230,10 @@ PASEO_PEER1_ID := "12D3KooWKjTeRJH8nMcFytc7qTTCQy7JrFgiZFr7iUjd1aPEBn8v" PASEO_PEER1_PORT := "10001" PASEO_PEER2_ID := "12D3KooWM8qgmWsh9ddbdX3kqR7W8tWuh62zhsdpwfs81eSnQuaH" PASEO_PEER2_PORT := "12347" +POLKADOT_PEER1_ID := "12D3KooWGgRm1jr8y5qKQYBAvjwfufdSVTLUnzeJacFdUmR8Sqvt" +POLKADOT_PEER1_PORT := "10001" +POLKADOT_PEER2_ID := "12D3KooWMbdwf9fEURv6BAAEBXM3raYDdcWCZYfiZA4eZHaFjYPd" +POLKADOT_PEER2_PORT := "12347" # Download and install Kubo IPFS binary @@ -299,6 +306,8 @@ ipfs-kubo-start test_dir runtime: ipfs-kubo-install PEERS='[{"ID":"{{ WESTEND_PEER1_ID }}","Addrs":["/ip4/127.0.0.1/tcp/{{ WESTEND_PEER1_PORT }}/ws"]},{"ID":"{{ WESTEND_PEER2_ID }}","Addrs":["/ip4/127.0.0.1/tcp/{{ WESTEND_PEER2_PORT }}/ws"]}]' elif [ "{{ runtime }}" = "bulletin-paseo-runtime" ]; then PEERS='[{"ID":"{{ PASEO_PEER1_ID }}","Addrs":["/ip4/127.0.0.1/tcp/{{ PASEO_PEER1_PORT }}/ws"]},{"ID":"{{ PASEO_PEER2_ID }}","Addrs":["/ip4/127.0.0.1/tcp/{{ PASEO_PEER2_PORT }}/ws"]}]' + elif [ "{{ runtime }}" = "bulletin-polkadot-runtime" ]; then + PEERS='[{"ID":"{{ POLKADOT_PEER1_ID }}","Addrs":["/ip4/127.0.0.1/tcp/{{ POLKADOT_PEER1_PORT }}/ws"]},{"ID":"{{ POLKADOT_PEER2_ID }}","Addrs":["/ip4/127.0.0.1/tcp/{{ POLKADOT_PEER2_PORT }}/ws"]}]' else echo "❌ Unhandled runtime: {{ runtime }}" exit 1 @@ -430,6 +439,8 @@ ipfs-start test_dir runtime: _check-docker PEERS="[{\"ID\":\"{{ WESTEND_PEER1_ID }}\",\"Addrs\":[\"${PEER_ADDR}/tcp/{{ WESTEND_PEER1_PORT }}/ws\"]},{\"ID\":\"{{ WESTEND_PEER2_ID }}\",\"Addrs\":[\"${PEER_ADDR}/tcp/{{ WESTEND_PEER2_PORT }}/ws\"]}]" elif [ "{{ runtime }}" = "bulletin-paseo-runtime" ]; then PEERS="[{\"ID\":\"{{ PASEO_PEER1_ID }}\",\"Addrs\":[\"${PEER_ADDR}/tcp/{{ PASEO_PEER1_PORT }}/ws\"]},{\"ID\":\"{{ PASEO_PEER2_ID }}\",\"Addrs\":[\"${PEER_ADDR}/tcp/{{ PASEO_PEER2_PORT }}/ws\"]}]" + elif [ "{{ runtime }}" = "bulletin-polkadot-runtime" ]; then + PEERS="[{\"ID\":\"{{ POLKADOT_PEER1_ID }}\",\"Addrs\":[\"${PEER_ADDR}/tcp/{{ POLKADOT_PEER1_PORT }}/ws\"]},{\"ID\":\"{{ POLKADOT_PEER2_ID }}\",\"Addrs\":[\"${PEER_ADDR}/tcp/{{ POLKADOT_PEER2_PORT }}/ws\"]}]" else echo "❌ Unhandled runtime: {{ runtime }}" exit 1 @@ -494,7 +505,7 @@ setup-services test_dir runtime ipfs_mode="kubo-docker": npm-install #!/usr/bin/env bash set -e - if [ "{{ runtime }}" = "bulletin-westend-runtime" ] || [ "{{ runtime }}" = "bulletin-paseo-runtime" ]; then + if [ "{{ runtime }}" = "bulletin-westend-runtime" ] || [ "{{ runtime }}" = "bulletin-paseo-runtime" ] || [ "{{ runtime }}" = "bulletin-polkadot-runtime" ]; then just bulletin-parachain-zombienet-start "{{ test_dir }}" "{{ runtime }}" else echo "❌ Unhandled runtime: {{ runtime }} specified!" @@ -591,6 +602,8 @@ run-test-authorize-and-store test_dir runtime mode="ws" ws_url="ws://127.0.0.1:1 PARACHAIN_CHAINSPEC_PATH="{{ test_dir }}/bulletin-westend-collator-2/cfg/westend-local-1010.json" elif [ "{{ runtime }}" = "bulletin-paseo-runtime" ]; then PARACHAIN_CHAINSPEC_PATH="{{ test_dir }}/bulletin-paseo-collator-2/cfg/westend-local-1501.json" + elif [ "{{ runtime }}" = "bulletin-polkadot-runtime" ]; then + PARACHAIN_CHAINSPEC_PATH="{{ test_dir }}/bulletin-polkadot-collator-2/cfg/westend-local-1010.json" else echo "❌ Unhandled runtime: {{ runtime }}" exit 1 @@ -800,6 +813,8 @@ run-authorize-and-store runtime mode="ws" ipfs_mode="kubo-docker": npm-install PARACHAIN_CHAINSPEC_PATH="$TEST_DIR/bulletin-westend-collator-2/cfg/westend-local-1010.json" elif [ "{{ runtime }}" = "bulletin-paseo-runtime" ]; then PARACHAIN_CHAINSPEC_PATH="$TEST_DIR/bulletin-paseo-collator-2/cfg/westend-local-1501.json" + elif [ "{{ runtime }}" = "bulletin-polkadot-runtime" ]; then + PARACHAIN_CHAINSPEC_PATH="$TEST_DIR/bulletin-polkadot-collator-2/cfg/westend-local-1010.json" else echo "❌ Unhandled runtime: {{ runtime }}" exit 1 diff --git a/scripts/create_bulletin_polkadot_spec.sh b/scripts/create_bulletin_polkadot_spec.sh new file mode 100755 index 000000000..64438e37f --- /dev/null +++ b/scripts/create_bulletin_polkadot_spec.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# +# Build the bulletin-polkadot runtime WASM from the Polkadot Fellows +# `runtimes` repo and generate the chain spec used by the local zombienet +# config. +# +# The runtime is not part of this Cargo workspace, so we clone the upstream +# repository at a configurable ref and build it out-of-tree. +# +# Override the source via env vars (defaults track Fellows PR #1170): +# FELLOWS_RUNTIMES_REPO - git URL (default: bkontur/runtimes fork) +# FELLOWS_RUNTIMES_REF - branch / tag / sha (default: bko-bulletin-stage1) +# FELLOWS_RUNTIMES_DIR - local checkout dir (default: target/fellows-runtimes) + +set -e + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" + +FELLOWS_RUNTIMES_REPO="${FELLOWS_RUNTIMES_REPO:-https://github.com/bkontur/runtimes.git}" +FELLOWS_RUNTIMES_REF="${FELLOWS_RUNTIMES_REF:-bko-bulletin-stage1}" +FELLOWS_RUNTIMES_DIR="${FELLOWS_RUNTIMES_DIR:-$ROOT_DIR/target/fellows-runtimes}" + +mkdir -p "$(dirname "$FELLOWS_RUNTIMES_DIR")" + +if [ ! -d "$FELLOWS_RUNTIMES_DIR/.git" ]; then + echo "📥 Cloning $FELLOWS_RUNTIMES_REPO into $FELLOWS_RUNTIMES_DIR..." + git clone --filter=blob:none "$FELLOWS_RUNTIMES_REPO" "$FELLOWS_RUNTIMES_DIR" +else + echo "♻️ Reusing existing checkout at $FELLOWS_RUNTIMES_DIR" + git -C "$FELLOWS_RUNTIMES_DIR" remote set-url origin "$FELLOWS_RUNTIMES_REPO" +fi + +echo "🔀 Fetching ref: $FELLOWS_RUNTIMES_REF..." +git -C "$FELLOWS_RUNTIMES_DIR" fetch --depth 1 origin "$FELLOWS_RUNTIMES_REF" +git -C "$FELLOWS_RUNTIMES_DIR" checkout -q FETCH_HEAD + +echo "🔨 Building bulletin-polkadot-runtime..." +(cd "$FELLOWS_RUNTIMES_DIR" && cargo build --release -p bulletin-polkadot-runtime) + +WASM_PATH="$FELLOWS_RUNTIMES_DIR/target/release/wbuild/bulletin-polkadot-runtime/bulletin_polkadot_runtime.compact.compressed.wasm" +if [ ! -f "$WASM_PATH" ]; then + echo "❌ Expected WASM not found at: $WASM_PATH" + exit 1 +fi + +cd "$ROOT_DIR" + +chain-spec-builder create \ + -p 1010 \ + -c westend \ + -i bulletin-polkadot \ + -n Bulletin \ + -t local \ + -r "$WASM_PATH" \ + named-preset local_testnet + +mv chain_spec.json ./zombienet/bulletin-polkadot-spec.json +echo "✅ Wrote ./zombienet/bulletin-polkadot-spec.json" diff --git a/scripts/runtimes-matrix.json b/scripts/runtimes-matrix.json index 443519df1..8d75fb44a 100644 --- a/scripts/runtimes-matrix.json +++ b/scripts/runtimes-matrix.json @@ -31,5 +31,17 @@ "pallet_xcm_benchmarks::generic": "templates/xcm-bench-template.hbs", "pallet_xcm_benchmarks::fungible": "templates/xcm-bench-template.hbs" } + }, + { + "name": "bulletin-polkadot", + "package": "bulletin-polkadot-runtime", + "path": "external/fellows-runtimes/system-parachains/bulletin/bulletin-polkadot", + "uris": [], + "integration_tests": true, + "experimental": true, + "external_runtime": { + "repo": "https://github.com/bkontur/runtimes.git", + "ref": "bko-bulletin-stage1" + } } ] diff --git a/zombienet/bulletin-polkadot-local.toml b/zombienet/bulletin-polkadot-local.toml new file mode 100644 index 000000000..c0e0073c7 --- /dev/null +++ b/zombienet/bulletin-polkadot-local.toml @@ -0,0 +1,67 @@ +# To run the network, execute the following command: +# +# cd +# ./scripts/create_bulletin_polkadot_spec.sh +# POLKADOT_BINARY_PATH=~/local_bridge_testing/bin/polkadot POLKADOT_PARACHAIN_BINARY_PATH=~/local_bridge_testing/bin/polkadot-parachain zombienet -p native spawn ./zombienet/bulletin-polkadot-local.toml + +[settings] +node_spawn_timeout = 240 + +[relaychain] +default_command = "{{POLKADOT_BINARY_PATH}}" +default_args = ["-lruntime=debug,xcm=trace"] +chain = "westend-local" + +[[relaychain.nodes]] +name = "alice" +validator = true +p2p_port = 30333 +rpc_port = 9942 +balance = 2000000000000 + +[[relaychain.nodes]] +name = "bob" +validator = true +p2p_port = 30433 +rpc_port = 9943 +balance = 2000000000000 + +[[parachains]] +id = 1010 +chain_spec_path = "./zombienet/bulletin-polkadot-spec.json" +cumulus_based = true + +[[parachains.collators]] +name = "bulletin-polkadot-collator-1" +command = "{{POLKADOT_PARACHAIN_BINARY_PATH}}" +validator = true +p2p_port = 10001 +rpc_port = 10000 +args = [ + "--ipfs-server", + "--pool-kbytes 65536", + "-lparachain=info,runtime=debug,xcm=trace,sub-libp2p::bitswap=trace,runtime::transaction-storage=trace", + # Embedded relay chain args (after "--"): + # Use -:--port to exclude zombienet's auto-generated --port flag, + # then provide --listen-addr to bind only on 127.0.0.1 (avoids litep2p + # IPv6 dual-stack crash on macOS and prevents 0.0.0.0 exposure). + "--", + "--listen-addr=/ip4/127.0.0.1/tcp/10003/ws", + "-:--port", +] + +[[parachains.collators]] +name = "bulletin-polkadot-collator-2" +command = "{{POLKADOT_PARACHAIN_BINARY_PATH}}" +validator = true +p2p_port = 12347 +rpc_port = 12346 +args = [ + "--ipfs-server", + "--pool-kbytes 65536", + "-lparachain=info,runtime=debug,xcm=trace,bitswap=trace,sub-libp2p::bitswap=trace,runtime::transaction-storage=trace", + # Embedded relay chain args (after "--"): + "--", + "--listen-addr=/ip4/127.0.0.1/tcp/12349/ws", + "-:--port", +] From dddc17769fb1f1806106c748ff55a8161b6c61a3 Mon Sep 17 00:00:00 2001 From: x3c41a Date: Fri, 8 May 2026 09:28:46 +0200 Subject: [PATCH 2/8] ci: drop continue-on-error from bulletin-polkadot steps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If chain-up or chopsticks fail for the experimental runtime we want a hard signal — silent failures defeat the point of running it in CI. --- .github/workflows/integration-test.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 80aef488d..0605d888f 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -188,7 +188,6 @@ jobs: - name: Start services working-directory: examples - continue-on-error: ${{ matrix.runtime.experimental == true }} env: RUNTIME_PACKAGE: ${{ matrix.runtime.package }} run: | @@ -200,8 +199,7 @@ jobs: # The remaining tests rely on signed `authorize_account` (TestAccounts / # Sudo), which the bulletin-polkadot Fellows runtime does not expose — # only Root and XCM from People can authorize. Skip them here until a - # local authorization path lands, but keep `Test chopsticks compatibility` - # in scope as a chain-up sanity check. + # local authorization path lands; chain-up + chopsticks still run. - name: Test authorize-and-store ws if: ${{ !matrix.runtime.experimental }} working-directory: examples @@ -234,7 +232,6 @@ jobs: - name: Test chopsticks compatibility working-directory: examples - continue-on-error: ${{ matrix.runtime.experimental == true }} run: just run-test-chopsticks "ws://127.0.0.1:10000" # SDK Client Tests From d5220ada6e6ba2d0269503f60dc44833d40ee91e Mon Sep 17 00:00:00 2001 From: x3c41a Date: Fri, 8 May 2026 09:37:35 +0200 Subject: [PATCH 3/8] ci: drop em dash from comment --- .github/workflows/integration-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 0605d888f..dc4a8890e 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -197,7 +197,7 @@ jobs: just KUBO_VERSION="${KUBO_VERSION}" start-services "$TEST_DIR" "$RUNTIME_PACKAGE" "kubo-native" # The remaining tests rely on signed `authorize_account` (TestAccounts / - # Sudo), which the bulletin-polkadot Fellows runtime does not expose — + # Sudo), which the bulletin-polkadot Fellows runtime does not expose: # only Root and XCM from People can authorize. Skip them here until a # local authorization path lands; chain-up + chopsticks still run. - name: Test authorize-and-store ws From 9e44eb1279790232a397f3fcc1740de3dbb76400 Mon Sep 17 00:00:00 2001 From: x3c41a Date: Fri, 8 May 2026 09:41:39 +0200 Subject: [PATCH 4/8] ci: split experimental runtimes into dedicated job The full integration-tests matrix excludes experimental entries via the runtime-matrix filter, dropping the per-step `if: !experimental` guards that were sprayed across the workflow. A second job runs only the smoke suite (chain-up + chopsticks) for experimental runtimes. --- .github/workflows/integration-test.yml | 115 +++++++++++++++++++++---- 1 file changed, 96 insertions(+), 19 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index dc4a8890e..05372750e 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -103,19 +103,23 @@ jobs: runs-on: ubuntu-latest outputs: runtime: ${{ steps.runtime.outputs.runtime }} + runtime_experimental: ${{ steps.runtime.outputs.runtime_experimental }} name: Extract tasks from matrix steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - id: runtime run: | - TASKS=$(jq '[.[] | select(.integration_tests == true)]' scripts/runtimes-matrix.json) + TASKS=$(jq '[.[] | select(.integration_tests == true and (.experimental // false) == false)]' scripts/runtimes-matrix.json) + EXPERIMENTAL=$(jq '[.[] | select(.integration_tests == true and (.experimental // false) == true)]' scripts/runtimes-matrix.json) SKIPPED=$(jq '[.[] | select(.integration_tests != true)]' scripts/runtimes-matrix.json) - echo "--- Running integration tests for ---" + echo "--- Running full integration tests for ---" echo "$TASKS" + echo "--- Running experimental smoke tests for ---" + echo "$EXPERIMENTAL" echo "--- Skipping integration tests for ---" echo "$SKIPPED" - TASKS=$(echo "$TASKS" | jq -c .) - echo "runtime=$TASKS" >> $GITHUB_OUTPUT + echo "runtime=$(echo "$TASKS" | jq -c .)" >> $GITHUB_OUTPUT + echo "runtime_experimental=$(echo "$EXPERIMENTAL" | jq -c .)" >> $GITHUB_OUTPUT integration-tests: needs: [set-image, setup, runtime-matrix] @@ -196,37 +200,27 @@ jobs: echo "RUNTIME_PACKAGE=${RUNTIME_PACKAGE}" >> "$GITHUB_ENV" just KUBO_VERSION="${KUBO_VERSION}" start-services "$TEST_DIR" "$RUNTIME_PACKAGE" "kubo-native" - # The remaining tests rely on signed `authorize_account` (TestAccounts / - # Sudo), which the bulletin-polkadot Fellows runtime does not expose: - # only Root and XCM from People can authorize. Skip them here until a - # local authorization path lands; chain-up + chopsticks still run. - name: Test authorize-and-store ws - if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just run-test-authorize-and-store "$TEST_DIR" "$RUNTIME_PACKAGE" "ws" - name: Test authorize-and-store smoldot - if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just run-test-authorize-and-store "$TEST_DIR" "$RUNTIME_PACKAGE" "smoldot" - name: Test store-chunked-data - if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just run-test-store-chunked-data "$TEST_DIR" - name: Test native-ipfs-dag-pb-chunked-data - if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just run-test-native-ipfs-dag-pb-chunked-data "$TEST_DIR" - name: Test store-big-data - if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just run-test-store-big-data "$TEST_DIR" "big32" - name: Test authorize-preimage-and-store - if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just run-test-authorize-preimage-and-store "$TEST_DIR" @@ -236,17 +230,14 @@ jobs: # SDK Client Tests - name: Test Rust SDK - if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just test-rust-sdk "${{ env.TEST_DIR }}" "$RUNTIME_PACKAGE" - name: Test TypeScript SDK - if: ${{ !matrix.runtime.experimental }} working-directory: examples run: just test-ts-sdk "${{ env.TEST_DIR }}" - name: Test TypeScript SDK (vitest integration) - if: ${{ !matrix.runtime.experimental }} working-directory: examples # TODO: https://github.com/paritytech/polkadot-bulletin-chain/issues/443 # Flaky chunked-store tests hit the per-tx timeout under CI load. @@ -256,7 +247,6 @@ jobs: run: just test-ts-sdk-vitest - name: Run console-ui tests - if: ${{ !matrix.runtime.experimental }} working-directory: console-ui run: just test @@ -282,9 +272,96 @@ jobs: path: | ${{ env.TEST_DIR }}/*.log + # Smoke tests for runtimes flagged `experimental` in runtimes-matrix.json. + # The bulletin-polkadot Fellows runtime exposes neither Sudo nor TestAccounts, + # so signed `authorize_account` paths exercised by the full suite don't apply. + # Verify chain-up and chopsticks compatibility only. + integration-tests-experimental: + needs: [set-image, setup, runtime-matrix] + if: ${{ needs.runtime-matrix.outputs.runtime_experimental != '[]' }} + name: Integration Tests (${{ matrix.runtime.name }}, experimental) + runs-on: parity-large + container: + image: ${{ needs.set-image.outputs.CI_IMAGE }} + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + runtime: ${{ fromJSON(needs.runtime-matrix.outputs.runtime_experimental) }} + + steps: + - name: Checkout sources + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + + - name: Load common environment variables via env file + run: cat .github/env >> $GITHUB_ENV + + - name: Rust cache (Bulletin) + uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 + with: + workspaces: . + shared-key: "bulletin-cache-bulletin-integration-tests-experimental-${{ matrix.runtime.name }}" + save-if: ${{ github.ref == 'refs/heads/main' }} + + - name: Setup Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'npm' + cache-dependency-path: examples/package.json + + - name: Install just + run: cargo install just --locked || true + + - name: Cache Polkadot SDK binaries + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ${{ env.POLKADOT_SDK_BIN_DIR }} + key: polkadot-sdk-${{ env.POLKADOT_SDK_VERSION }}-binaries + - name: Cache Zombienet + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: ${{ env.ZOMBIENET_BIN_DIR }} + key: zombienet-${{ env.ZOMBIENET_VERSION }}-binaries + - name: Add binaries to PATH + run: | + chmod +x "${POLKADOT_SDK_BIN_DIR}"/* + chmod +x "${ZOMBIENET_BIN_DIR}"/* + echo "${POLKADOT_SDK_BIN_DIR}" >> "$GITHUB_PATH" + echo "${ZOMBIENET_BIN_DIR}" >> "$GITHUB_PATH" + echo "SKIP_PARACHAIN_SETUP=1" >> "$GITHUB_ENV" + echo "ZOMBIENET_BINARY=zombienet-linux-x64" >> "$GITHUB_ENV" + + - name: Start services + working-directory: examples + env: + RUNTIME_PACKAGE: ${{ matrix.runtime.package }} + run: | + TEST_DIR="$(mktemp -d $GITHUB_WORKSPACE/bulletin-tests-run-XXXXX)/test" + echo "TEST_DIR=$TEST_DIR" >> "$GITHUB_ENV" + echo "RUNTIME_PACKAGE=${RUNTIME_PACKAGE}" >> "$GITHUB_ENV" + just KUBO_VERSION="${KUBO_VERSION}" start-services "$TEST_DIR" "$RUNTIME_PACKAGE" "kubo-native" + + - name: Test chopsticks compatibility + working-directory: examples + run: just run-test-chopsticks "ws://127.0.0.1:10000" + + - name: Stop services + if: always() + working-directory: examples + run: just KUBO_VERSION="${KUBO_VERSION}" stop-services "$TEST_DIR" "kubo-native" + + - name: Upload Zombienet logs (on failure) + if: failure() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: failed-zombienet-logs-${{ matrix.runtime.name }} + path: | + ${{ env.TEST_DIR }}/*.log + integration-tests-complete: name: All integration tests passed - needs: [changes, integration-tests] + needs: [changes, integration-tests, integration-tests-experimental] if: always() runs-on: ubuntu-latest steps: From 2e987564f6775953d3cf0dafa89f58b97f1a1bfa Mon Sep 17 00:00:00 2001 From: x3c41a Date: Mon, 11 May 2026 09:57:43 +0200 Subject: [PATCH 5/8] ci: run bulletin-polkadot through the regular integration-tests job Per review, drop the experimental flag + dedicated job. The runtime ships through the same matrix as bulletin-westend/paseo so the full suite runs against it. --- .github/workflows/integration-test.yml | 101 ++----------------------- scripts/runtimes-matrix.json | 1 - 2 files changed, 5 insertions(+), 97 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 05372750e..3923933f1 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -103,23 +103,19 @@ jobs: runs-on: ubuntu-latest outputs: runtime: ${{ steps.runtime.outputs.runtime }} - runtime_experimental: ${{ steps.runtime.outputs.runtime_experimental }} name: Extract tasks from matrix steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - id: runtime run: | - TASKS=$(jq '[.[] | select(.integration_tests == true and (.experimental // false) == false)]' scripts/runtimes-matrix.json) - EXPERIMENTAL=$(jq '[.[] | select(.integration_tests == true and (.experimental // false) == true)]' scripts/runtimes-matrix.json) + TASKS=$(jq '[.[] | select(.integration_tests == true)]' scripts/runtimes-matrix.json) SKIPPED=$(jq '[.[] | select(.integration_tests != true)]' scripts/runtimes-matrix.json) - echo "--- Running full integration tests for ---" + echo "--- Running integration tests for ---" echo "$TASKS" - echo "--- Running experimental smoke tests for ---" - echo "$EXPERIMENTAL" echo "--- Skipping integration tests for ---" echo "$SKIPPED" - echo "runtime=$(echo "$TASKS" | jq -c .)" >> $GITHUB_OUTPUT - echo "runtime_experimental=$(echo "$EXPERIMENTAL" | jq -c .)" >> $GITHUB_OUTPUT + TASKS=$(echo "$TASKS" | jq -c .) + echo "runtime=$TASKS" >> $GITHUB_OUTPUT integration-tests: needs: [set-image, setup, runtime-matrix] @@ -272,96 +268,9 @@ jobs: path: | ${{ env.TEST_DIR }}/*.log - # Smoke tests for runtimes flagged `experimental` in runtimes-matrix.json. - # The bulletin-polkadot Fellows runtime exposes neither Sudo nor TestAccounts, - # so signed `authorize_account` paths exercised by the full suite don't apply. - # Verify chain-up and chopsticks compatibility only. - integration-tests-experimental: - needs: [set-image, setup, runtime-matrix] - if: ${{ needs.runtime-matrix.outputs.runtime_experimental != '[]' }} - name: Integration Tests (${{ matrix.runtime.name }}, experimental) - runs-on: parity-large - container: - image: ${{ needs.set-image.outputs.CI_IMAGE }} - timeout-minutes: 60 - strategy: - fail-fast: false - matrix: - runtime: ${{ fromJSON(needs.runtime-matrix.outputs.runtime_experimental) }} - - steps: - - name: Checkout sources - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - - name: Load common environment variables via env file - run: cat .github/env >> $GITHUB_ENV - - - name: Rust cache (Bulletin) - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 - with: - workspaces: . - shared-key: "bulletin-cache-bulletin-integration-tests-experimental-${{ matrix.runtime.name }}" - save-if: ${{ github.ref == 'refs/heads/main' }} - - - name: Setup Node.js - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 - with: - node-version: ${{ env.NODE_VERSION }} - cache: 'npm' - cache-dependency-path: examples/package.json - - - name: Install just - run: cargo install just --locked || true - - - name: Cache Polkadot SDK binaries - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 - with: - path: ${{ env.POLKADOT_SDK_BIN_DIR }} - key: polkadot-sdk-${{ env.POLKADOT_SDK_VERSION }}-binaries - - name: Cache Zombienet - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 - with: - path: ${{ env.ZOMBIENET_BIN_DIR }} - key: zombienet-${{ env.ZOMBIENET_VERSION }}-binaries - - name: Add binaries to PATH - run: | - chmod +x "${POLKADOT_SDK_BIN_DIR}"/* - chmod +x "${ZOMBIENET_BIN_DIR}"/* - echo "${POLKADOT_SDK_BIN_DIR}" >> "$GITHUB_PATH" - echo "${ZOMBIENET_BIN_DIR}" >> "$GITHUB_PATH" - echo "SKIP_PARACHAIN_SETUP=1" >> "$GITHUB_ENV" - echo "ZOMBIENET_BINARY=zombienet-linux-x64" >> "$GITHUB_ENV" - - - name: Start services - working-directory: examples - env: - RUNTIME_PACKAGE: ${{ matrix.runtime.package }} - run: | - TEST_DIR="$(mktemp -d $GITHUB_WORKSPACE/bulletin-tests-run-XXXXX)/test" - echo "TEST_DIR=$TEST_DIR" >> "$GITHUB_ENV" - echo "RUNTIME_PACKAGE=${RUNTIME_PACKAGE}" >> "$GITHUB_ENV" - just KUBO_VERSION="${KUBO_VERSION}" start-services "$TEST_DIR" "$RUNTIME_PACKAGE" "kubo-native" - - - name: Test chopsticks compatibility - working-directory: examples - run: just run-test-chopsticks "ws://127.0.0.1:10000" - - - name: Stop services - if: always() - working-directory: examples - run: just KUBO_VERSION="${KUBO_VERSION}" stop-services "$TEST_DIR" "kubo-native" - - - name: Upload Zombienet logs (on failure) - if: failure() - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: failed-zombienet-logs-${{ matrix.runtime.name }} - path: | - ${{ env.TEST_DIR }}/*.log - integration-tests-complete: name: All integration tests passed - needs: [changes, integration-tests, integration-tests-experimental] + needs: [changes, integration-tests] if: always() runs-on: ubuntu-latest steps: diff --git a/scripts/runtimes-matrix.json b/scripts/runtimes-matrix.json index 8d75fb44a..a13bd9c4f 100644 --- a/scripts/runtimes-matrix.json +++ b/scripts/runtimes-matrix.json @@ -38,7 +38,6 @@ "path": "external/fellows-runtimes/system-parachains/bulletin/bulletin-polkadot", "uris": [], "integration_tests": true, - "experimental": true, "external_runtime": { "repo": "https://github.com/bkontur/runtimes.git", "ref": "bko-bulletin-stage1" From 4574f5e1108ef0e0a50fce053ae745d55e6e4a87 Mon Sep 17 00:00:00 2001 From: x3c41a Date: Wed, 13 May 2026 09:38:50 +0200 Subject: [PATCH 6/8] ci: split external runtime build out of the spec script - runtimes-matrix.json: nest `path` under `external_runtime`, add the production `uris` so try-runtime migration checks pick it up. - create_bulletin_polkadot_spec.sh: only run chain-spec-builder; take the WASM via `WASM_PATH`. - justfile: new `build-external-runtime` recipe handles clone+build, prints the WASM path. - integration-test.yml: resolve Fellows commit sha, cache the WASM build on that key, build before `Start services`. --- .github/workflows/integration-test.yml | 27 +++++++++++ examples/justfile | 57 +++++++++++++++++++++++- scripts/create_bulletin_polkadot_spec.sh | 39 +++------------- scripts/runtimes-matrix.json | 8 ++-- 4 files changed, 95 insertions(+), 36 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 3923933f1..7dea3bbe1 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -186,6 +186,33 @@ jobs: echo "${ZOMBIENET_BIN_DIR}" >> "$GITHUB_PATH" echo "ZOMBIENET_BINARY=zombienet-linux-x64" >> "$GITHUB_ENV" + # Resolve the Fellows commit sha and key the WASM cache on it so subsequent + # runs skip the multi-minute out-of-tree build. + - name: Resolve external runtime ref + if: ${{ matrix.runtime.external_runtime != null }} + id: external-runtime + run: | + REPO='${{ matrix.runtime.external_runtime.repo }}' + REF='${{ matrix.runtime.external_runtime.ref }}' + SHA=$(git ls-remote "$REPO" "$REF" | awk '{print $1}' | head -n1) + if [ -z "$SHA" ]; then + echo "❌ Failed to resolve $REF in $REPO" + exit 1 + fi + echo "sha=$SHA" >> "$GITHUB_OUTPUT" + + - name: Cache external runtime build + if: ${{ matrix.runtime.external_runtime != null }} + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: target/external-runtimes/${{ matrix.runtime.name }} + key: external-runtime-${{ matrix.runtime.name }}-${{ steps.external-runtime.outputs.sha }} + + - name: Build external runtime + if: ${{ matrix.runtime.external_runtime != null }} + working-directory: examples + run: just build-external-runtime ${{ matrix.runtime.name }} > /dev/null + - name: Start services working-directory: examples env: diff --git a/examples/justfile b/examples/justfile index 85044931b..9d61bf1d2 100644 --- a/examples/justfile +++ b/examples/justfile @@ -151,6 +151,7 @@ bulletin-parachain-zombienet-start test_dir runtime="bulletin-westend-runtime": fi # Pick spec script + zombienet TOML based on the runtime + SPEC_ENV=() if [ "{{ runtime }}" = "bulletin-westend-runtime" ]; then SPEC_SCRIPT="create_bulletin_westend_spec.sh" ZOMBIENET_TOML="zombienet/bulletin-westend-local.toml" @@ -160,6 +161,9 @@ bulletin-parachain-zombienet-start test_dir runtime="bulletin-westend-runtime": elif [ "{{ runtime }}" = "bulletin-polkadot-runtime" ]; then SPEC_SCRIPT="create_bulletin_polkadot_spec.sh" ZOMBIENET_TOML="zombienet/bulletin-polkadot-local.toml" + # Runtime lives out-of-tree: build (or reuse cached) WASM first. + WASM_PATH="$(just build-external-runtime bulletin-polkadot)" + SPEC_ENV+=(WASM_PATH="$WASM_PATH") else echo "❌ Unhandled runtime: {{ runtime }}" exit 1 @@ -168,7 +172,7 @@ bulletin-parachain-zombienet-start test_dir runtime="bulletin-westend-runtime": # Create chain spec echo " Creating chain spec for {{ runtime }}..." ROOT_DIR="{{ justfile_directory() }}/.." - PATH="$HOME/local_bulletin_testing/bin:$PATH" "$ROOT_DIR/scripts/$SPEC_SCRIPT" + env "${SPEC_ENV[@]}" PATH="$HOME/local_bulletin_testing/bin:$PATH" "$ROOT_DIR/scripts/$SPEC_SCRIPT" cat <, builds the +# runtime package, and prints the path to the compressed WASM on stdout. +# +# In CI, cache `target/external-runtimes/` keyed by the resolved +# Fellows commit sha (use `git ls-remote ` to resolve) to skip +# the rebuild on cache hit. +build-external-runtime name: + #!/usr/bin/env bash + set -e + ROOT_DIR="{{ justfile_directory() }}/.." + MATRIX="$ROOT_DIR/scripts/runtimes-matrix.json" + + REPO=$(jq -er --arg n "{{ name }}" '.[] | select(.name == $n) | .external_runtime.repo' "$MATRIX") + REF=$(jq -er --arg n "{{ name }}" '.[] | select(.name == $n) | .external_runtime.ref' "$MATRIX") + SUBPATH=$(jq -er --arg n "{{ name }}" '.[] | select(.name == $n) | .external_runtime.path' "$MATRIX") + PACKAGE=$(jq -er --arg n "{{ name }}" '.[] | select(.name == $n) | .package' "$MATRIX") + + CHECKOUT_DIR="$ROOT_DIR/target/external-runtimes/{{ name }}" + WASM_PATH="$CHECKOUT_DIR/target/release/wbuild/$PACKAGE/${PACKAGE//-/_}.compact.compressed.wasm" + + >&2 echo "🔧 build-external-runtime: {{ name }} from $REPO @ $REF ($SUBPATH)" + + mkdir -p "$(dirname "$CHECKOUT_DIR")" + if [ ! -d "$CHECKOUT_DIR/.git" ]; then + >&2 echo "📥 Cloning $REPO into $CHECKOUT_DIR..." + git clone --filter=blob:none "$REPO" "$CHECKOUT_DIR" >&2 + else + git -C "$CHECKOUT_DIR" remote set-url origin "$REPO" + fi + + >&2 echo "🔀 Fetching ref: $REF..." + git -C "$CHECKOUT_DIR" fetch --depth 1 origin "$REF" >&2 + git -C "$CHECKOUT_DIR" checkout -q FETCH_HEAD + + if [ ! -f "$WASM_PATH" ]; then + >&2 echo "🔨 Building $PACKAGE..." + (cd "$CHECKOUT_DIR/$SUBPATH" && cargo build --release -p "$PACKAGE" >&2) + else + >&2 echo "♻️ Reusing cached WASM at $WASM_PATH" + fi + + if [ ! -f "$WASM_PATH" ]; then + >&2 echo "❌ WASM not produced at: $WASM_PATH" + exit 1 + fi + + echo "$WASM_PATH" + # Check if Docker is available and running _check-docker: #!/usr/bin/env bash diff --git a/scripts/create_bulletin_polkadot_spec.sh b/scripts/create_bulletin_polkadot_spec.sh index 64438e37f..10ccf6582 100755 --- a/scripts/create_bulletin_polkadot_spec.sh +++ b/scripts/create_bulletin_polkadot_spec.sh @@ -1,46 +1,21 @@ #!/usr/bin/env bash # -# Build the bulletin-polkadot runtime WASM from the Polkadot Fellows -# `runtimes` repo and generate the chain spec used by the local zombienet -# config. +# Generate the zombienet chain spec for bulletin-polkadot from a pre-built +# runtime WASM. The runtime lives in the polkadot-fellows/runtimes repo and +# is built out-of-tree (see the `build-external-runtime` justfile recipe). # -# The runtime is not part of this Cargo workspace, so we clone the upstream -# repository at a configurable ref and build it out-of-tree. -# -# Override the source via env vars (defaults track Fellows PR #1170): -# FELLOWS_RUNTIMES_REPO - git URL (default: bkontur/runtimes fork) -# FELLOWS_RUNTIMES_REF - branch / tag / sha (default: bko-bulletin-stage1) -# FELLOWS_RUNTIMES_DIR - local checkout dir (default: target/fellows-runtimes) +# Env vars: +# WASM_PATH - path to bulletin_polkadot_runtime.compact.compressed.wasm set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" -FELLOWS_RUNTIMES_REPO="${FELLOWS_RUNTIMES_REPO:-https://github.com/bkontur/runtimes.git}" -FELLOWS_RUNTIMES_REF="${FELLOWS_RUNTIMES_REF:-bko-bulletin-stage1}" -FELLOWS_RUNTIMES_DIR="${FELLOWS_RUNTIMES_DIR:-$ROOT_DIR/target/fellows-runtimes}" - -mkdir -p "$(dirname "$FELLOWS_RUNTIMES_DIR")" - -if [ ! -d "$FELLOWS_RUNTIMES_DIR/.git" ]; then - echo "📥 Cloning $FELLOWS_RUNTIMES_REPO into $FELLOWS_RUNTIMES_DIR..." - git clone --filter=blob:none "$FELLOWS_RUNTIMES_REPO" "$FELLOWS_RUNTIMES_DIR" -else - echo "♻️ Reusing existing checkout at $FELLOWS_RUNTIMES_DIR" - git -C "$FELLOWS_RUNTIMES_DIR" remote set-url origin "$FELLOWS_RUNTIMES_REPO" -fi - -echo "🔀 Fetching ref: $FELLOWS_RUNTIMES_REF..." -git -C "$FELLOWS_RUNTIMES_DIR" fetch --depth 1 origin "$FELLOWS_RUNTIMES_REF" -git -C "$FELLOWS_RUNTIMES_DIR" checkout -q FETCH_HEAD - -echo "🔨 Building bulletin-polkadot-runtime..." -(cd "$FELLOWS_RUNTIMES_DIR" && cargo build --release -p bulletin-polkadot-runtime) +: "${WASM_PATH:?WASM_PATH must be set (path to bulletin_polkadot_runtime.compact.compressed.wasm)}" -WASM_PATH="$FELLOWS_RUNTIMES_DIR/target/release/wbuild/bulletin-polkadot-runtime/bulletin_polkadot_runtime.compact.compressed.wasm" if [ ! -f "$WASM_PATH" ]; then - echo "❌ Expected WASM not found at: $WASM_PATH" + echo "❌ WASM not found at: $WASM_PATH" exit 1 fi diff --git a/scripts/runtimes-matrix.json b/scripts/runtimes-matrix.json index a13bd9c4f..d21a62cf6 100644 --- a/scripts/runtimes-matrix.json +++ b/scripts/runtimes-matrix.json @@ -35,12 +35,14 @@ { "name": "bulletin-polkadot", "package": "bulletin-polkadot-runtime", - "path": "external/fellows-runtimes/system-parachains/bulletin/bulletin-polkadot", - "uris": [], + "uris": [ + "wss://bulletin-rpc.polkadot.io" + ], "integration_tests": true, "external_runtime": { "repo": "https://github.com/bkontur/runtimes.git", - "ref": "bko-bulletin-stage1" + "ref": "bko-bulletin-stage1", + "path": "./system-parachains/bulletin/bulletin-polkadot" } } ] From 0f86c8e70b115521bc5299163343feee9c5300c3 Mon Sep 17 00:00:00 2001 From: x3c41a Date: Thu, 14 May 2026 17:29:01 +0200 Subject: [PATCH 7/8] ci: run check-migrations against bulletin-polkadot via external build The check-runtime-migration workflow used `cargo build -p $PACKAGE` on the local workspace, which doesn't work for runtimes that live in an out-of-tree repo (bulletin-polkadot lives in the fellows runtimes fork). When the matrix entry has `external_runtime`, resolve the upstream sha, cache the build under `target/external-runtimes/-try-runtime`, and build via just; then point try-runtime at the resulting WASM. Local-workspace runtimes still go through the original cargo path. The just recipe now takes optional features and routes feature variants to separate checkout directories so caches don't collide with the no-features build used by integration-tests. --- .github/workflows/check-runtime-migration.yml | 50 +++++++++++++++++-- examples/justfile | 33 ++++++++---- scripts/runtimes-matrix.json | 3 ++ 3 files changed, 71 insertions(+), 15 deletions(-) diff --git a/.github/workflows/check-runtime-migration.yml b/.github/workflows/check-runtime-migration.yml index 3ec6a3975..26dc13676 100644 --- a/.github/workflows/check-runtime-migration.yml +++ b/.github/workflows/check-runtime-migration.yml @@ -179,20 +179,60 @@ jobs: key: try-runtime-snapshot-${{ matrix.runtime.name }}- fail-on-cache-miss: true + # Resolve the external commit sha and key the WASM cache on it so subsequent + # runs skip the multi-minute out-of-tree build. + - name: Resolve external runtime ref + if: ${{ matrix.runtime.external_runtime != null }} + id: external-runtime + run: | + REPO='${{ matrix.runtime.external_runtime.repo }}' + REF='${{ matrix.runtime.external_runtime.ref }}' + SHA=$(git ls-remote "$REPO" "$REF" | awk '{print $1}' | head -n1) + if [ -z "$SHA" ]; then + echo "❌ Failed to resolve $REF in $REPO" + exit 1 + fi + echo "sha=$SHA" >> "$GITHUB_OUTPUT" + + - name: Cache external runtime build (try-runtime) + if: ${{ matrix.runtime.external_runtime != null }} + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 + with: + path: target/external-runtimes/${{ matrix.runtime.name }}-try-runtime + key: external-runtime-try-runtime-${{ matrix.runtime.name }}-${{ steps.external-runtime.outputs.sha }} + + - name: Install just + if: ${{ matrix.runtime.external_runtime != null }} + run: cargo install just --locked || true + + - name: Build external runtime (try-runtime) + if: ${{ matrix.runtime.external_runtime != null }} + working-directory: examples + run: just build-external-runtime ${{ matrix.runtime.name }} "try-runtime" > /dev/null + - name: Run ${{ matrix.runtime.name }} Runtime Checks env: PACKAGE_NAME: ${{ matrix.runtime.package }} + RUNTIME_NAME: ${{ matrix.runtime.name }} + IS_EXTERNAL: ${{ matrix.runtime.external_runtime != null }} TRY_RUNTIME_SPEC_NAME_CHECK: ${{ matrix.runtime.try_runtime.spec_name_check}} TRY_RUNTIME_EXTRA_FLAGS: ${{ matrix.runtime.try_runtime.extra_flags }} run: | try-runtime --version - FEATURES="try-runtime" - echo "Setting features: ${FEATURES}" - cargo build --release -p "$PACKAGE_NAME" --features "$FEATURES" -q --locked - RUNTIME_BLOB_NAME=$(echo "$PACKAGE_NAME" | sed 's/-/_/g').compact.compressed.wasm - RUNTIME_BLOB_PATH="./target/release/wbuild/$PACKAGE_NAME/$RUNTIME_BLOB_NAME" + + if [ "$IS_EXTERNAL" = "true" ]; then + # External runtime was built by the previous step; locate the WASM + # in the external checkout's target directory. + RUNTIME_BLOB_PATH="./target/external-runtimes/${RUNTIME_NAME}-try-runtime/target/release/wbuild/$PACKAGE_NAME/$RUNTIME_BLOB_NAME" + else + FEATURES="try-runtime" + echo "Setting features: ${FEATURES}" + cargo build --release -p "$PACKAGE_NAME" --features "$FEATURES" -q --locked + RUNTIME_BLOB_PATH="./target/release/wbuild/$PACKAGE_NAME/$RUNTIME_BLOB_NAME" + fi + export RUST_LOG=remote-ext=debug,runtime=trace (set -x; try-runtime \ diff --git a/examples/justfile b/examples/justfile index 9d61bf1d2..2dc11f560 100644 --- a/examples/justfile +++ b/examples/justfile @@ -197,13 +197,15 @@ bulletin-parachain-zombienet-start test_dir runtime="bulletin-westend-runtime": # Build a runtime that lives in an external (Fellows) repo. # Reads `external_runtime.{repo,ref,path}` and `package` from # scripts/runtimes-matrix.json for the given matrix `name`. Clones into -# {{ justfile_directory() }}/../target/external-runtimes/, builds the -# runtime package, and prints the path to the compressed WASM on stdout. +# {{ justfile_directory() }}/../target/external-runtimes/[-], +# builds the runtime package (optionally with the given comma-separated +# `features`), and prints the path to the compressed WASM on stdout. # -# In CI, cache `target/external-runtimes/` keyed by the resolved -# Fellows commit sha (use `git ls-remote ` to resolve) to skip -# the rebuild on cache hit. -build-external-runtime name: +# In CI, cache `target/external-runtimes/[-]` keyed by the +# resolved Fellows commit sha (use `git ls-remote ` to resolve) +# to skip the rebuild on cache hit. Different feature sets get separate +# checkouts so caches don't collide. +build-external-runtime name features="": #!/usr/bin/env bash set -e ROOT_DIR="{{ justfile_directory() }}/.." @@ -214,10 +216,16 @@ build-external-runtime name: SUBPATH=$(jq -er --arg n "{{ name }}" '.[] | select(.name == $n) | .external_runtime.path' "$MATRIX") PACKAGE=$(jq -er --arg n "{{ name }}" '.[] | select(.name == $n) | .package' "$MATRIX") - CHECKOUT_DIR="$ROOT_DIR/target/external-runtimes/{{ name }}" + FEATURES="{{ features }}" + if [ -n "$FEATURES" ]; then + VARIANT_SUFFIX="-$(echo "$FEATURES" | tr ',' '-' | tr -cd 'a-zA-Z0-9-')" + else + VARIANT_SUFFIX="" + fi + CHECKOUT_DIR="$ROOT_DIR/target/external-runtimes/{{ name }}${VARIANT_SUFFIX}" WASM_PATH="$CHECKOUT_DIR/target/release/wbuild/$PACKAGE/${PACKAGE//-/_}.compact.compressed.wasm" - >&2 echo "🔧 build-external-runtime: {{ name }} from $REPO @ $REF ($SUBPATH)" + >&2 echo "🔧 build-external-runtime: {{ name }} from $REPO @ $REF ($SUBPATH) [features=${FEATURES:-default}]" mkdir -p "$(dirname "$CHECKOUT_DIR")" if [ ! -d "$CHECKOUT_DIR/.git" ]; then @@ -231,9 +239,14 @@ build-external-runtime name: git -C "$CHECKOUT_DIR" fetch --depth 1 origin "$REF" >&2 git -C "$CHECKOUT_DIR" checkout -q FETCH_HEAD + BUILD_ARGS=(--release -p "$PACKAGE") + if [ -n "$FEATURES" ]; then + BUILD_ARGS+=(--features "$FEATURES") + fi + if [ ! -f "$WASM_PATH" ]; then - >&2 echo "🔨 Building $PACKAGE..." - (cd "$CHECKOUT_DIR/$SUBPATH" && cargo build --release -p "$PACKAGE" >&2) + >&2 echo "🔨 Building $PACKAGE [features=${FEATURES:-default}]..." + (cd "$CHECKOUT_DIR/$SUBPATH" && cargo build "${BUILD_ARGS[@]}" >&2) else >&2 echo "♻️ Reusing cached WASM at $WASM_PATH" fi diff --git a/scripts/runtimes-matrix.json b/scripts/runtimes-matrix.json index d21a62cf6..efbcd0879 100644 --- a/scripts/runtimes-matrix.json +++ b/scripts/runtimes-matrix.json @@ -39,6 +39,9 @@ "wss://bulletin-rpc.polkadot.io" ], "integration_tests": true, + "try_runtime": { + "extra_flags": "--blocktime 24000 --disable-spec-version-check" + }, "external_runtime": { "repo": "https://github.com/bkontur/runtimes.git", "ref": "bko-bulletin-stage1", From ce61364154f30f29d8194d99a3e764e44a76f9b2 Mon Sep 17 00:00:00 2001 From: x3c41a Date: Fri, 15 May 2026 10:08:29 +0200 Subject: [PATCH 8/8] ci: point bulletin-polkadot matrix at the configurable-authorizers port The external runtime ref now targets x3c41a/runtimes@ndk/port-pr405, which bumps the bulletin pallet deps past 0.2.0-draft and wires #405's `EnsureAllowedAuthorizers` + `allowed_authorizers` genesis seed into the runtime. This is what unblocks the local-zombienet authorize-and-store tests for bulletin-polkadot, which were failing with BadSigner because the previous Authorizer was Root | XCM-from-People only. Move the matrix back to bkontur/runtimes once #405 is upstreamed there. --- scripts/runtimes-matrix.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/runtimes-matrix.json b/scripts/runtimes-matrix.json index efbcd0879..9668d81fe 100644 --- a/scripts/runtimes-matrix.json +++ b/scripts/runtimes-matrix.json @@ -43,8 +43,8 @@ "extra_flags": "--blocktime 24000 --disable-spec-version-check" }, "external_runtime": { - "repo": "https://github.com/bkontur/runtimes.git", - "ref": "bko-bulletin-stage1", + "repo": "https://github.com/x3c41a/runtimes.git", + "ref": "ndk/port-pr405", "path": "./system-parachains/bulletin/bulletin-polkadot" } }