ci: temp full-matrix branch validation run (all 11 combos) #31
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: Publish Testnode | |
| # On a version tag (or manual dispatch), publish a testnode image for every | |
| # variant x nitro-contracts-version we support. Each image's chain state is | |
| # GENERATED inline in CI by running `init` (no pre-built snapshot release | |
| # bundles, nothing to publish out of band). The intended (variant x version) | |
| # matrix and the init flags per combo come from runtime.mjs resolvePublishMatrix. | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| # TEMP (validation): branch-scoped trigger to test this rewrite end-to-end | |
| # before merge. Scopes the matrix to one combo. REMOVE before merge. | |
| branches: | |
| - ci/generate-snapshots | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: "Image version tag (default: tag on push, else apps/cli package version)" | |
| required: false | |
| default: "" | |
| type: string | |
| variant: | |
| description: "Variant to publish (or all)" | |
| required: true | |
| default: "all" | |
| type: choice | |
| options: | |
| - all | |
| - l2 | |
| - l2-timeboost | |
| - l3-eth | |
| - l3-custom-6 | |
| - l3-custom-16 | |
| - l3-custom-18 | |
| - l3-custom-20 | |
| nitro-contracts-version: | |
| description: "Nitro contracts version (or all)" | |
| required: true | |
| default: "all" | |
| type: choice | |
| options: | |
| - all | |
| - v2.1 | |
| - v3.2 | |
| jobs: | |
| resolve-publish-matrix: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.matrix.outputs.matrix }} | |
| version: ${{ steps.ver.outputs.version }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Resolve image version | |
| id: ver | |
| run: | | |
| set -euo pipefail | |
| if [ "${{ github.ref_type }}" = "tag" ]; then | |
| V="${{ github.ref_name }}" | |
| elif [ -n "${{ inputs.version }}" ]; then | |
| V="${{ inputs.version }}" | |
| else | |
| V="v$(node -p "require('./apps/cli/package.json').version")" | |
| fi | |
| echo "version=$V" >> "$GITHUB_OUTPUT" | |
| echo "resolved image version: $V" | |
| - name: Build publish matrix | |
| id: matrix | |
| env: | |
| # On tag push: every variant x every supported version. On dispatch: | |
| # the chosen filters. resolvePublishMatrix only emits supported combos | |
| # (e.g. no v2.1 for L2-only variants). | |
| # TEMP (validation): a branch push runs the full matrix (all combos). | |
| # REMOVE with the branch trigger above before merge (revert to the | |
| # tag/dispatch form). | |
| VARIANT_FILTER: ${{ github.ref_type == 'tag' && 'all' || (github.event_name == 'workflow_dispatch' && inputs.variant || 'all') }} | |
| VERSION_FILTER: ${{ github.ref_type == 'tag' && 'all' || (github.event_name == 'workflow_dispatch' && inputs.nitro-contracts-version || 'all') }} | |
| run: >- | |
| node --input-type=module -e | |
| "import { resolvePublishMatrix } from './packages/testnode/src/runtime.mjs'; | |
| const include = resolvePublishMatrix(process.env.VARIANT_FILTER, process.env.VERSION_FILTER); | |
| if (!include.length) throw new Error('empty publish matrix'); | |
| console.error('publish matrix:', JSON.stringify(include)); | |
| const { appendFileSync } = await import('node:fs'); | |
| appendFileSync(process.env.GITHUB_OUTPUT, 'matrix=' + JSON.stringify({ include }) + '\\n');" | |
| publish-testnode-image: | |
| needs: resolve-publish-matrix | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 75 | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJson(needs.resolve-publish-matrix.outputs.matrix) }} | |
| permissions: | |
| contents: read | |
| packages: write | |
| env: | |
| # init resolves token-bridge-contracts to <repo-parent>/token-bridge-contracts; | |
| # pin the location and the commit the contract-deployer Dockerfiles use. | |
| TOKEN_BRIDGE_LOCAL_DIR: ${{ github.workspace }}/../token-bridge-contracts | |
| TOKEN_BRIDGE_COMMIT: 5975d8f7360816341be7f94fd333ef240f4aec23 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: 20 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Install Foundry (forge for token-bridge build) | |
| uses: foundry-rs/foundry-toolchain@v1 | |
| - name: Install yarn (classic) | |
| run: npm install -g yarn@1.22.22 | |
| - name: Prepare token-bridge-contracts host checkout | |
| run: | | |
| set -euxo pipefail | |
| mkdir -p "$TOKEN_BRIDGE_LOCAL_DIR" | |
| cd "$TOKEN_BRIDGE_LOCAL_DIR" | |
| git init . | |
| git remote add origin https://github.com/OffchainLabs/token-bridge-contracts.git | |
| git fetch --depth 1 origin "$TOKEN_BRIDGE_COMMIT" | |
| git checkout --detach FETCH_HEAD | |
| yarn install --frozen-lockfile | |
| yarn build | |
| test -f node_modules/ts-node/dist/bin.js | |
| test -f scripts/deployment/deployTokenBridgeCreator.ts | |
| # Generate this combo's snapshot inline via init. init is flaky in CI | |
| # (intermittently exits 0 at wait-l1 before capturing, ~50%), so success | |
| # is driven off the manifest existing, with up to 3 attempts and a reset | |
| # between. --skip-post-capture-verify because the in-place verify-restart's | |
| # fixed 120s RPC budget is too tight for a cold runner. | |
| - name: Generate snapshot (init, retry until captured) | |
| env: | |
| SNAPSHOT_ID: ${{ matrix.snapshotId }} | |
| NC_VERSION: ${{ matrix.contractsVersion }} | |
| DECIMALS: ${{ matrix.feeTokenDecimals }} | |
| TIMEBOOST: ${{ matrix.timeboostEnabled }} | |
| run: | | |
| set -uo pipefail | |
| MANIFEST="config/snapshots/$SNAPSHOT_ID/manifest.json" | |
| EXTRA="" | |
| if [ -n "${DECIMALS:-}" ] && [ "${DECIMALS}" != "null" ]; then | |
| EXTRA="$EXTRA --fee-token-decimals $DECIMALS" | |
| fi | |
| if [ "${TIMEBOOST:-}" = "true" ]; then | |
| EXTRA="$EXTRA --timeboost-enabled" | |
| fi | |
| max=3 | |
| for attempt in $(seq 1 "$max"); do | |
| echo "::group::init attempt $attempt/$max ($SNAPSHOT_ID)" | |
| # shellcheck disable=SC2086 | |
| pnpm dev init \ | |
| --nitro-contracts-version "$NC_VERSION" \ | |
| $EXTRA \ | |
| --capture-id "$SNAPSHOT_ID" \ | |
| --rebuild \ | |
| --skip-post-capture-verify || echo "init exited non-zero on attempt $attempt" | |
| echo "::endgroup::" | |
| if [ -f "$MANIFEST" ]; then | |
| echo "snapshot captured on attempt $attempt" | |
| break | |
| fi | |
| echo "attempt $attempt produced no snapshot; resetting and retrying" | |
| docker compose -f docker/docker-compose.yaml -p arbitrum-testnode down -v || true | |
| done | |
| test -f "$MANIFEST" | |
| - name: Dump docker state on failure | |
| if: failure() | |
| run: | | |
| docker ps -a || true | |
| docker compose -f docker/docker-compose.yaml -p arbitrum-testnode logs --tail=100 || true | |
| - name: Prepare testnode context | |
| run: >- | |
| node scripts/ci/prepare-testnode-context.mjs | |
| --variant "${{ matrix.variant }}" | |
| --snapshot-id "${{ matrix.snapshotId }}" | |
| --nitro-contracts-version "${{ matrix.contractsVersion }}" | |
| - name: Lowercase owner | |
| id: lower | |
| run: echo "owner=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT" | |
| - name: Contracts tag | |
| id: nc | |
| run: echo "tag=nc$(echo '${{ matrix.contractsVersion }}' | sed 's/^v//')" >> "$GITHUB_OUTPUT" | |
| - name: Log in to GHCR | |
| uses: docker/login-action@v3 | |
| with: | |
| registry: ghcr.io | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build and push testnode image | |
| uses: docker/build-push-action@v6 | |
| with: | |
| context: . | |
| file: docker/testnode.Dockerfile | |
| push: true | |
| tags: ghcr.io/${{ steps.lower.outputs.owner }}/arbitrum-testnode-ci:${{ needs.resolve-publish-matrix.outputs.version }}-${{ steps.nc.outputs.tag }}-${{ matrix.variant }} |