diff --git a/.github/actions/setup-solo-stack/action.yml b/.github/actions/setup-solo-stack/action.yml deleted file mode 100644 index 77c844b0..00000000 --- a/.github/actions/setup-solo-stack/action.yml +++ /dev/null @@ -1,127 +0,0 @@ -name: Setup Solo Stack -description: Deploy a Solo Falcon stack for local Hedera network tests. - -inputs: - solo-version: - description: Solo CLI version used for Falcon deploy. - required: false - default: '0.72.0' - network-tag: - description: Consensus / network node container image tag (--release-tag). - required: false - default: 'v0.72.0' - mirror-tag: - description: Mirror node chart/image version (--mirror-node-version). - required: false - default: 'v0.151.0' - relay-tag: - description: JSON-RPC relay image/chart tag (--relay-release). - required: false - default: '0.76.2' - external-address: - description: Bind address for Solo kubectl port-forwards. - required: false - default: '127.0.0.1' - -outputs: - deployment_name: - description: Solo deployment name. - value: ${{ steps.solo_deploy.outputs.deployment_name }} - namespace: - description: Kubernetes namespace used by the Solo deployment. - value: ${{ steps.solo_deploy.outputs.namespace }} - -runs: - using: composite - steps: - - name: Generate falcon-values config file - shell: bash - run: | - cat > .github/falcon.yml <> "$GITHUB_OUTPUT" - echo "namespace=$solo_ns" >> "$GITHUB_OUTPUT" - - npx "@hashgraph/solo@$SOLO_VERSION" one-shot falcon deploy \ - --values-file .github/falcon.yml \ - --dev \ - --deploy-explorer=false \ - --deployment "$solo_deployment" \ - --namespace "$solo_ns" \ - --external-address "$EXTERNAL_ADDRESS" - - - name: Forward compatibility ports - shell: bash - env: - SOLO_NS: ${{ steps.solo_deploy.outputs.namespace }} - run: | - set -euo pipefail - - kubectl -n "$SOLO_NS" get svc haproxy-node1-svc - kubectl -n "$SOLO_NS" port-forward svc/haproxy-node1-svc 50211:50211 & - echo "Forwarding svc/haproxy-node1-svc -> localhost:50211 (consensus gRPC)" - - if kubectl -n "$SOLO_NS" get svc mirror-1-web3 &>/dev/null; then - kubectl -n "$SOLO_NS" port-forward svc/mirror-1-web3 8545:80 & - echo "Forwarding svc/mirror-1-web3 -> localhost:8545 (mirror Web3)" - else - echo "::warning::svc/mirror-1-web3 not found in $SOLO_NS; skipping 8545 forward" - fi - - sleep 3 - - - name: Verify Mirror REST API - shell: bash - run: | - set -euo pipefail - - echo "Waiting for mirror node REST API..." - for i in $(seq 1 30); do - response=$(curl -sf http://localhost:38081/api/v1/accounts 2>/dev/null || true) - if echo "$response" | grep -q '"accounts"'; then - echo "Mirror REST API is up." - exit 0 - fi - echo "Attempt ${i}/30: not ready, retrying in 10s..." - sleep 10 - done - - echo "ERROR: Mirror REST API did not become available." - exit 1 diff --git a/.github/workflows/support/scripts/setup-solo-stack.sh b/.github/workflows/support/scripts/setup-solo-stack.sh new file mode 100755 index 00000000..00f8e4f2 --- /dev/null +++ b/.github/workflows/support/scripts/setup-solo-stack.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: Apache-2.0 +# +# Deploys Solo Falcon one-shot on Kind. Expects repo root as cwd and Kind tooling +# already installed (e.g. via helm/kind-action). Writes deployment_name and +# namespace to GITHUB_OUTPUT when set (GitHub Actions). + +set -euo pipefail + +NETWORK_TAG="${NETWORK_TAG:-v0.72.0}" +MIRROR_TAG="${MIRROR_TAG:-v0.151.0}" +RELAY_TAG="${RELAY_TAG:-0.76.2}" +SOLO_VERSION="${SOLO_VERSION:-0.72.0}" +EXTERNAL_ADDRESS="${EXTERNAL_ADDRESS:-127.0.0.1}" + +cat >.github/falcon.yml <>"${GITHUB_OUTPUT}" +fi + +npx "@hashgraph/solo@${SOLO_VERSION}" one-shot falcon deploy \ + --values-file .github/falcon.yml \ + --dev \ + --deploy-explorer=false \ + --deployment "${SOLO_DEPLOYMENT}" \ + --namespace "${SOLO_NS}" \ + --external-address "${EXTERNAL_ADDRESS}" + +echo "Waiting for mirror node REST API..." +for i in $(seq 1 30); do + response=$(curl -sf http://localhost:38081/api/v1/accounts 2>/dev/null || true) + if echo "${response}" | grep -q '"accounts"'; then + echo "Mirror REST API is up." + exit 0 + fi + echo "Attempt ${i}/30: not ready, retrying in 10s..." + sleep 10 +done + +echo "ERROR: Mirror REST API did not become available." +exit 1 diff --git a/.github/workflows/support/scripts/solo-kubectl-port-forward.sh b/.github/workflows/support/scripts/solo-kubectl-port-forward.sh new file mode 100755 index 00000000..257c20b4 --- /dev/null +++ b/.github/workflows/support/scripts/solo-kubectl-port-forward.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: Apache-2.0 +# +# Starts background kubectl port-forward processes so localhost matches the +# expectations of `@hashgraph/sdk` local-node consumers (127.0.0.1:50211 → +# consensus via HAProxy) and the mirror Web3 endpoint (127.0.0.1:8545 → +# svc/mirror-1-web3), consistent with hiero-sdk-js solo-lib.js. +# +# Required environment: +# SOLO_NAMESPACE — Kubernetes namespace from the Solo deploy step +# (e.g. steps..outputs.namespace). + +set -euo pipefail + +NS="${SOLO_NAMESPACE:?SOLO_NAMESPACE is required}" + +kubectl get svc haproxy-node1-svc -n "${NS}" +kubectl port-forward -n "${NS}" svc/haproxy-node1-svc 50211:50211 & +echo "Forwarding svc/haproxy-node1-svc -> localhost:50211 (consensus gRPC for local-node)" + +if kubectl get svc mirror-1-web3 -n "${NS}" &>/dev/null; then + kubectl port-forward -n "${NS}" svc/mirror-1-web3 8545:80 & + echo "Forwarding svc/mirror-1-web3 -> localhost:8545 (mirror Web3)" +else + echo "::warning::svc/mirror-1-web3 not found in ${NS}; skipping 8545 forward" +fi + +sleep 3 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 375fabee..6a3d9363 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -40,7 +40,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: - node-version: '20' + node-version: 22 - name: Install Foundry uses: step-security/foundry-toolchain@01e2d127ea061e2ce8fa34340de71ca8518f093e # v1.2.1 @@ -76,7 +76,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: - node-version: '20' + node-version: 22 - name: Install Foundry uses: step-security/foundry-toolchain@01e2d127ea061e2ce8fa34340de71ca8518f093e # v1.2.1 @@ -115,7 +115,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: - node-version: '20' + node-version: 22 - name: Install Foundry uses: step-security/foundry-toolchain@01e2d127ea061e2ce8fa34340de71ca8518f093e # v1.2.1 @@ -154,7 +154,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: - node-version: '20' + node-version: 22 - name: Install Foundry uses: step-security/foundry-toolchain@01e2d127ea061e2ce8fa34340de71ca8518f093e # v1.2.1 @@ -190,7 +190,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: - node-version: '20' + node-version: 22 - name: Install Foundry uses: step-security/foundry-toolchain@01e2d127ea061e2ce8fa34340de71ca8518f093e # v1.2.1 @@ -232,7 +232,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: - node-version: '20' + node-version: 22 - name: Install Dependencies run: npm ci @@ -359,7 +359,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: - node-version: '20' + node-version: 22 - name: Install Foundry uses: step-security/foundry-toolchain@01e2d127ea061e2ce8fa34340de71ca8518f093e # v1.2.1 @@ -397,7 +397,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: - node-version: 20 + node-version: 22 - name: Install Foundry uses: step-security/foundry-toolchain@01e2d127ea061e2ce8fa34340de71ca8518f093e # v1.2.1 @@ -410,11 +410,27 @@ jobs: - name: Install Dependencies run: npm ci - - name: Set up Solo stack - id: solo_stack - uses: ./.github/actions/setup-solo-stack + - name: Setup Kind + uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0 with: - solo-version: ${{ env.SOLO_VERSION }} + install_only: true + node_image: kindest/node:v1.32.5@sha256:e3b2327e3a5ab8c76f5ece68936e4cafaa82edf58486b769727ab0b3b97a5b0d + version: v0.29.0 + kubectl_version: v1.32.5 + verbosity: 3 + wait: 120s + + - name: Deploy local Hiero network (Solo / Kind) + id: solo_stack + run: bash .github/workflows/support/scripts/setup-solo-stack.sh + env: + SOLO_VERSION: ${{ env.SOLO_VERSION }} + timeout-minutes: 15 + + - name: Solo kubectl port forwards (50211 / 8545) + run: bash .github/workflows/support/scripts/solo-kubectl-port-forward.sh + env: + SOLO_NAMESPACE: ${{ steps.solo_stack.outputs.namespace }} - name: Run Forge build on Foundry HTS example run: forge build @@ -439,7 +455,7 @@ jobs: test $TOKEN_CODE != "0x" working-directory: examples/foundry-hts - - name: Destroy Solo stack + - name: One-shot Falcon destroy if: always() run: | npx @hashgraph/solo@${{ env.SOLO_VERSION }} one-shot falcon destroy \ @@ -472,7 +488,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3 with: - node-version: '20' + node-version: 22 - name: Install Foundry uses: step-security/foundry-toolchain@01e2d127ea061e2ce8fa34340de71ca8518f093e # v1.2.1 @@ -485,16 +501,32 @@ jobs: - name: Install Dependencies run: npm ci - - name: Set up Solo stack - id: solo_stack - uses: ./.github/actions/setup-solo-stack + - name: Setup Kind + uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # v1.14.0 with: - solo-version: ${{ env.SOLO_VERSION }} + install_only: true + node_image: kindest/node:v1.32.5@sha256:e3b2327e3a5ab8c76f5ece68936e4cafaa82edf58486b769727ab0b3b97a5b0d + version: v0.29.0 + kubectl_version: v1.32.5 + verbosity: 3 + wait: 120s + + - name: Deploy local Hiero network (Solo / Kind) + id: solo_stack + run: bash .github/workflows/support/scripts/setup-solo-stack.sh + env: + SOLO_VERSION: ${{ env.SOLO_VERSION }} + timeout-minutes: 15 + + - name: Solo kubectl port forwards (50211 / 8545) + run: bash .github/workflows/support/scripts/solo-kubectl-port-forward.sh + env: + SOLO_NAMESPACE: ${{ steps.solo_stack.outputs.namespace }} - name: Run e2e Validation Tests run: npm run test:e2e - - name: Destroy Solo stack + - name: One-shot Falcon destroy if: always() run: | npx @hashgraph/solo@${{ env.SOLO_VERSION }} one-shot falcon destroy \