Repository navigation
fix: restore examples CI reliability #363
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Test Examples | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # Formatting is repo-wide, so it runs once rather than per-example. | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20.20" | |
| - name: Enable Corepack | |
| run: | | |
| corepack enable | |
| corepack prepare yarn@1.22.22 --activate | |
| - name: Check formatting | |
| run: bash scripts/check-prettier.sh | |
| # Emit the list of examples as a JSON array so the test job can fan out one | |
| # runner per example via a matrix. Single source of truth: scripts/projects.sh. | |
| list-examples: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.set.outputs.matrix }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - id: set | |
| run: | | |
| # shellcheck source=scripts/projects.sh | |
| . scripts/projects.sh | |
| echo "matrix=$(projects_json)" >> "$GITHUB_OUTPUT" | |
| # One job per example. Each runs on its own runner so building/testing a single | |
| # example keeps disk usage bounded — building every example on one runner was | |
| # exhausting disk. fail-fast: false so one failing example doesn't cancel the | |
| # rest. Each job builds + tests exactly its example via scripts/test-example.sh. | |
| test-example: | |
| needs: list-examples | |
| name: test (${{ matrix.example }}) | |
| runs-on: | |
| labels: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| example: ${{ fromJSON(needs.list-examples.outputs.matrix) }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| # Pin >=20.18 — @solana/codecs-numbers (via @solana/web3.js) rejects older 20.x. | |
| # act's amd64 toolcache ships 20.11 unless a specific version is requested. | |
| node-version: "20.20" | |
| - name: Enable Corepack | |
| run: | | |
| corepack enable | |
| # Pre-download yarn before test-locally.sh forks parallel `yarn install` | |
| # runs; otherwise corepack races on ~/.cache/node/corepack/yarn/* and | |
| # leaves a broken shim (MODULE_NOT_FOUND on lib/cli). | |
| corepack prepare yarn@1.22.19 --activate | |
| corepack prepare yarn@1.22.22 --activate | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| toolchain: "1.89.0" | |
| # anchor idl build invokes the host `stable` toolchain after cargo build-sbf. | |
| # dtolnay/rust-toolchain only installs 1.89.0; without stable, act/CI fails with | |
| # "Missing manifest in toolchain 'stable-x86_64-unknown-linux-gnu'". | |
| - name: Ensure stable Rust for Anchor IDL | |
| run: | | |
| rustup toolchain install stable --profile minimal | |
| rustup default 1.89.0 | |
| - name: Install native dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y libudev-dev pkg-config | |
| - name: Install Solana | |
| run: | | |
| sh -c "$(curl -sSfL https://release.anza.xyz/v3.1.9/install)" | |
| echo "$HOME/.local/share/solana/install/active_release/bin" >> $GITHUB_PATH | |
| - name: Install Anchor | |
| run: | | |
| cargo install --git https://github.com/solana-foundation/anchor --tag v1.0.2 anchor-cli | |
| - name: Install MagicBlock Ephemeral Validator | |
| run: | | |
| # Provides ephemeral-validator, query-filtering-service, vrf-oracle and | |
| # mb-test-validator — every binary test-locally.sh needs. | |
| npm install -g @magicblock-labs/ephemeral-validator@latest | |
| - name: Configure Solana | |
| env: | |
| DEVNET_KEYPAIR_JSON: ${{ secrets.DEVNET_KEYPAIR_JSON }} | |
| run: | | |
| solana config set --url localhost | |
| mkdir -p ~/.config/solana | |
| if [ -n "$DEVNET_KEYPAIR_JSON" ]; then | |
| # Use the funded devnet keypair for both local and TEE/devnet runs. | |
| printf '%s' "$DEVNET_KEYPAIR_JSON" > ~/.config/solana/id.json | |
| chmod 600 ~/.config/solana/id.json | |
| echo "::notice title=CI test wallet::This run uses wallet mbtN3ztb3qDeuLYv951EmyfxLbLsitwVjBTiHmnLSNv. TEE/devnet tests deploy from it — top up with: solana airdrop 5 mbtN3ztb3qDeuLYv951EmyfxLbLsitwVjBTiHmnLSNv --url devnet" | |
| else | |
| # No secret → fresh ephemeral keypair. Best-effort devnet airdrop so the | |
| # wallet has a little SOL for any devnet-touching ops (faucet rate-limits | |
| # may reject; that's fine since TEE tests are also skipped in this branch). | |
| solana-keygen new --no-bip39-passphrase --silent --outfile ~/.config/solana/id.json | |
| solana airdrop 2 \ | |
| "$(solana-keygen pubkey ~/.config/solana/id.json)" \ | |
| --url devnet || echo "Airdrop failed (faucet rate-limited or down) — continuing." | |
| fi | |
| - name: Test ${{ matrix.example }} | |
| env: | |
| # Optional override for the base-layer devnet RPC (TEE examples only). | |
| # Useful to point at a private endpoint with higher rate limits than | |
| # api.devnet.solana.com. The WS URL is auto-derived from this. | |
| # If unset, the script falls back to the public RPC. | |
| DEVNET_RPC_URL: ${{ secrets.DEVNET_RPC_URL }} | |
| run: | | |
| sudo sysctl -w fs.inotify.max_user_instances=1280 | |
| sudo sysctl -w fs.inotify.max_user_watches=655360 | |
| sudo sysctl -w fs.file-max=2097152 | |
| sudo prlimit --pid $$ --nofile=1000000:1000000 | |
| bash scripts/test-example.sh "${{ matrix.example }}" |