name: Build on: workflow_dispatch: pull_request: push: branches: - main permissions: contents: read jobs: # Run the full Tilt build and wait for it to converge tilt: # in the future, we may want to run cheap lints, tests, and builds before firing up the expensive tilt test. # But for now, we'll kick-off everything at once # needs: [go-lint-and-tests, node, algorand, ethereum, terra, rust-lint-and-tests] runs-on: tilt-kube-public # Cancel previous builds on the same branch/ref. Full runs are expensive # and capacity is limited, so we want to avoid running multiple builds # in parallel even if it means skipping CI runs on permanent branches # (unfortunately, we can't differentiate between temporary and permanent # refs without duplicating the entire logic). concurrency: group: ${{ github.workflow }}-tilt-${{ github.ref }} cancel-in-progress: true steps: - name: Clear repository run: | rm -rf $GITHUB_WORKSPACE && mkdir $GITHUB_WORKSPACE - uses: actions/checkout@v2 - name: Expand for link to Tilt dashboard (only available during build) run: > echo "Tilt progress dashboard: https://$DASHBOARD_URL" - run: | kubectl config set-context ci --namespace=$DEPLOY_NS kubectl config use-context ci - run: tilt ci --timeout 45m0s -- --ci --namespace=$DEPLOY_NS --num=2 timeout-minutes: 60 # Clean up k8s resources - run: kubectl delete --namespace=$DEPLOY_NS service,statefulset,configmap,pod,job --all if: always() # Verify whether the Makefile builds the node (no dependencies other than Go) node: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v2 - uses: actions/setup-go@v2 with: go-version: "1.23.3" - run: make node algorand: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v3 with: python-version: "3.10" - run: pip install -r algorand/requirements.txt - run: cd algorand && make test ethereum: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: "22" - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 - run: cd ethereum && make test-push0 && make test relayer-ethereum: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: "22" - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 - run: cd relayer/ethereum && make test-push0 && make test ethereum-upgrade: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: "22" - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 - run: cd clients/js && make install - run: cd ethereum && make test-upgrade solana: runs-on: ubuntu-24.04 container: ghcr.io/wormhole-foundation/solana:1.10.31@sha256:d31e8db926a1d3fbaa9d9211d9979023692614b7b64912651aba0383e8c01bad env: RUSTFLAGS: -Dwarnings EMITTER_ADDRESS: CiByUvEcx7w2HA4VHcPCBUAFQ73Won9kB36zW9VjirSr BRIDGE_ADDRESS: Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o CHAIN_ID: 1 steps: - uses: actions/checkout@v3 - name: Get rust toolchain version id: toolchain run: | RUST_VERSION="$(awk '/channel =/ { print substr($3, 2, length($3)-2) }' solana/rust-toolchain)" echo "::set-output name=version::${RUST_VERSION}" - name: Get solana version id: solana run: | SOLANA_VERSION="$(awk '/solana-program =/ { print substr($3, 3, length($3)-3) }' solana/bridge/program/Cargo.toml)" echo "::set-output name=version::${SOLANA_VERSION}" - name: Cache rust toolchain uses: actions/cache@v3 env: cache-name: solana-toolchain with: path: | ~/.cargo/bin ~/.rustup key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ steps.toolchain.outputs.version }} restore-keys: | ${{ runner.os }}-build-${{ env.cache-name }}- ${{ runner.os }}-build- ${{ runner.os }}- - name: Install rust toolchain uses: dtolnay/rust-toolchain@55c7845fad90d0ae8b2e83715cb900e5e861e8cb with: toolchain: ${{ steps.toolchain.outputs.version }} components: "clippy,rustfmt" - name: Cache rust packages / build cache uses: actions/cache@v3 env: cache-name: solana-rust-packages with: path: | ~/.cargo/bin ~/.cargo/registry ~/.cargo/git/db solana/target key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('solana/Cargo.lock') }} restore-keys: | ${{ runner.os }}-build-${{ env.cache-name }}- ${{ runner.os }}-build- ${{ runner.os }}- - name: Run `cargo fmt` run: cargo fmt --check --all --manifest-path solana/Cargo.toml - name: Run `cargo check` run: cargo check --workspace --tests --manifest-path solana/Cargo.toml --features "nft-bridge/instructions token-bridge/instructions wormhole-bridge-solana/instructions" - name: Run `cargo clippy` run: cargo clippy --workspace --tests --manifest-path solana/Cargo.toml --features "nft-bridge/instructions token-bridge/instructions wormhole-bridge-solana/instructions" - name: Run unit tests env: RUST_BACKTRACE: "1" run: | cd solana export BPF_OUT_DIR="$(pwd)/target/deploy" export PATH="${HOME}/.local/share/solana/install/active_release/bin:${PATH}" mkdir -p "${BPF_OUT_DIR}" cp external/mpl_token_metadata.so "${BPF_OUT_DIR}" BPF_PACKAGES=( bridge/program/Cargo.toml modules/token_bridge/program/Cargo.toml modules/nft_bridge/program/Cargo.toml ) for p in "${BPF_PACKAGES[@]}"; do cargo build-bpf --manifest-path "${p}" done cargo test --workspace --features "nft-bridge/instructions token-bridge/instructions wormhole-bridge-solana/instructions" shell: bash aptos: name: Aptos runs-on: ubuntu-24.04 defaults: run: shell: bash working-directory: ./aptos steps: - name: Checkout repository uses: actions/checkout@v2 - name: Run tests via docker run: make test-docker sui: name: Sui runs-on: ubuntu-24.04 steps: - name: Checkout repository uses: actions/checkout@v2 - name: Run tests via docker run: cd sui && make test-docker # NOTE: While Terra2 is deprecated, this job may be related to testing CosmWasm functionality in Wormchain. terra-2: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: "22" - run: cd cosmwasm/deployment/terra2 && make test cosmwasm: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: "22" - run: cd cosmwasm && make test cli: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: "22" - run: | cd clients/js && make test make docs git diff --name-only --exit-code && echo "✅ Generated CLI docs match committed docs" || (echo "❌ Generated CLI docs differs from committed CLI docs, run \`make docs\` and commit the result" >&2 && exit 1) # Verify wormhole chain unit tests wormchain: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v2 - uses: actions/setup-go@v2 with: go-version: "1.19.9" - run: | cd wormchain make proto -B git diff --name-only --exit-code && echo "✅ Generated proto matches committed proto" || (echo "❌ Generated proto differs from committed proto, run \`make proto -B\` and commit the result" >&2 && exit 1) make test # Verify go sdk unit/fuzz tests sdk_vaa: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v2 - uses: actions/setup-go@v2 with: go-version: "1.23.3" - run: cd sdk/vaa && go test && go test -v -fuzz FuzzCalculateQuorum -run FuzzCalculateQuorum -fuzztime 15s # Run Go linters node-lint: # The linter is slow enough that we want to run it on the self-hosted runner runs-on: tilt-kube-public concurrency: group: ${{ github.workflow }}-lint-${{ github.ref }} cancel-in-progress: true steps: - name: Clear repository run: | rm -rf $GITHUB_WORKSPACE && mkdir $GITHUB_WORKSPACE - uses: actions/checkout@v2 - uses: actions/setup-go@v2 with: go-version: "1.23.3" - name: Install formatter run: go install golang.org/x/tools/cmd/goimports@v0.8.0 - name: Formatting checks run: ./scripts/lint.sh -l -g format - name: Install linters run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.5.0 - name: Run linters run: make generate && golangci-lint --version && ./scripts/lint.sh -g lint - name: Ensure generated proto matches run: | rm -rf node/pkg/proto docker build --target go-export -f Dockerfile.proto -o type=local,dest=node . git diff --name-only --exit-code && echo "✅ Generated proto matches committed proto" || (echo "❌ Generated proto differs from committed proto, run \`rm -rf node/pkg/proto && docker build --target go-export -f Dockerfile.proto -o type=local,dest=node .\` and commit the result" >&2 && exit 1) spellcheck: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # Pinned version of the v6 tag, which is a lightweight and hence mutable tag - uses: streetsidesoftware/cspell-action@214db1e3138f326d33b7a6a51c92852e89ab0618 with: # For now, only lint markdown files files: "**/*.md" inline: warning # Only check files in the PR or push incremental_files_only: true # Run Go tests node-tests: # The tests are slow enough that we want to run it on the self-hosted runner runs-on: tilt-kube-public concurrency: group: ${{ github.workflow }}-test-${{ github.ref }} cancel-in-progress: true steps: - name: Clear repository run: | rm -rf $GITHUB_WORKSPACE && mkdir $GITHUB_WORKSPACE - uses: actions/checkout@v2 - uses: actions/setup-go@v2 with: go-version: "1.23.3" # The go-ethereum and celo-blockchain packages both implement secp256k1 using the exact same header, but that causes duplicate symbols. - name: Run golang tests run: cd node && go test -v -timeout 5m -race ./... # Run Rust lints and tests rust-lint-and-tests: runs-on: ubuntu-24.04 env: # Deny all warnings. Since we also build with stable, this causes newly-added clippy lints to fail when new Rust # versions are released. This means that the CI runs will occasionally fail as new warnings are flagged in the # codebase, but it's a good way to force us to keep the codebase in good shape. RUSTFLAGS: -Dwarnings strategy: matrix: manifest: # NOTE: The `test_args` flag is used to forward job-specific flags to Rust tests while allowing us to use the matrix strategy for configuring jobs. # CosmWasm - path: cosmwasm/Cargo.toml args: "--workspace --locked --exclude 'shutdown-*'" test_args: "" - path: cosmwasm/Cargo.toml args: "-p 'shutdown-*' --no-default-features --locked" test_args: "" # Rust SDK - path: sdk/rust/Cargo.toml args: "--all-features --all-targets" test_args: "" # SVM directory (shims code) - path: svm/wormhole-core-shims/Cargo.toml args: "--workspace --no-default-features --features solana" # The crate by default requires environment variables. If solana is specified, mainnet values are used. test_args: "--lib" # Skip integration tests; they require compiled BPF programs - path: svm/wormhole-core-shims/anchor/Cargo.toml args: "--workspace" test_args: "--lib" # Skip doctests; anchor interfaces lack solana_program dependency name: rust-lint-and-tests (${{ matrix.manifest.path }}) steps: - name: Check out source uses: actions/checkout@v3 - name: Get rust toolchain version id: toolchain env: MANIFEST: ${{ matrix.manifest.path }} run: | WORKSPACE_DIR="$(dirname "${MANIFEST}")" if [ -f "${WORKSPACE_DIR}/rust-toolchain.toml" ]; then # Extract the Rust version from rust-toolchain.toml # Searches for lines matching 'channel =' and extracts the quoted version string # Example: 'channel = "1.83.0"' -> extracts "1.83.0" by: # $3 = third field ("1.83.0") # substr($3, 2, length($3)-2) = strips first and last character (the quotes) RUST_VERSION="$(awk '/channel =/ { print substr($3, 2, length($3)-2) }' "${WORKSPACE_DIR}/rust-toolchain.toml")" else RUST_VERSION="stable" fi echo "::set-output name=version::${RUST_VERSION}" - name: Install rust toolchain uses: dtolnay/rust-toolchain@55c7845fad90d0ae8b2e83715cb900e5e861e8cb with: toolchain: ${{ steps.toolchain.outputs.version }} components: "clippy,rustfmt" - name: Create cache key id: cachekey env: MANIFEST: ${{ matrix.manifest.path }} run: | LOCKFILE="$(dirname "${MANIFEST}")/Cargo.lock" NAME="${MANIFEST%%/*}" HASH="$(sha256sum "${LOCKFILE}" | awk '{ print $1 }')" echo "::set-output name=name::${NAME}" echo "::set-output name=hash::${HASH}" - name: Cache rust packages uses: actions/cache@v3 with: path: ~/.cargo/registry key: ${{ runner.os }}-build-${{ steps.cachekey.outputs.name }}-${{ steps.cachekey.outputs.hash }} restore-keys: | ${{ runner.os }}-build-${{ matrix.manifest.path }}- - name: Run `rustfmt` run: cd $(dirname ${{ matrix.manifest.path }}) && cargo fmt --check - name: Run `cargo clippy` run: cargo clippy ${{ matrix.manifest.args }} --tests --manifest-path ${{ matrix.manifest.path }} - name: Run unit tests run: cargo test ${{ matrix.manifest.args }} ${{ matrix.manifest.test_args }} --manifest-path ${{ matrix.manifest.path }} docker: runs-on: ubuntu-latest steps: - name: Check out source uses: actions/checkout@v2 - run: chmod 755 ./scripts/check-docker-pin.sh - run: ./scripts/check-docker-pin.sh npm-packages: runs-on: ubuntu-latest steps: - name: Check out source uses: actions/checkout@v2 - run: chmod 755 ./scripts/check-npm-package-scopes.sh - run: ./scripts/check-npm-package-scopes.sh prettier: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: "22" - run: npx prettier@2.3.2 --check ./clients/js/src ./sdk/js/src