Skip to content

ci: temp full-matrix branch validation run (all 11 combos) #31

ci: temp full-matrix branch validation run (all 11 combos)

ci: temp full-matrix branch validation run (all 11 combos) #31

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 }}