Publish Testnode #40
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: | |
| push: | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| inputs: | |
| name: | |
| description: "Testnode name from config/testnodes.json (provides defaults for the inputs below)" | |
| required: false | |
| default: "" | |
| type: string | |
| version: | |
| description: "Pinned testnode image version tag (overrides config/testnodes.json)" | |
| required: false | |
| default: "" | |
| type: string | |
| snapshot-version: | |
| description: "Snapshot release tag to use for every selected variant (overrides config/testnodes.json)" | |
| required: false | |
| default: "" | |
| type: string | |
| snapshot-repo: | |
| description: "GitHub repo in owner/repo form that hosts the tagged snapshot release" | |
| required: false | |
| default: "" | |
| type: string | |
| variant: | |
| description: "Named variant to publish" | |
| required: true | |
| default: "l3-eth" | |
| 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 baked into the snapshot" | |
| required: true | |
| default: "v3.2" | |
| type: choice | |
| options: | |
| - all | |
| - v2.1 | |
| - v3.2 | |
| jobs: | |
| resolve-publish-matrix: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| matrix: ${{ steps.matrix.outputs.matrix }} | |
| version: ${{ steps.resolve.outputs.version }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Resolve testnode inputs | |
| id: resolve | |
| env: | |
| # On a tag push, publish every variant in every nitro-contracts version | |
| # so we can test against either. Each variant installs its own | |
| # pre-generated snapshot bundle (per-variant snapshotReleaseTag in | |
| # runtime.mjs), so snapshot-version here is unused for publishing and | |
| # passed only to satisfy resolve-testnode.mjs. The matrix builder skips | |
| # variant x version combos that have no snapshot bundle. | |
| TESTNODE_NAME: ${{ github.event_name == 'push' && '' || inputs.name }} | |
| TESTNODE_VERSION: ${{ github.event_name == 'push' && github.ref_name || inputs.version }} | |
| TESTNODE_SNAPSHOT_VERSION: ${{ github.event_name == 'push' && github.ref_name || inputs.snapshot-version }} | |
| TESTNODE_VARIANT: ${{ github.event_name == 'push' && 'all' || inputs.variant }} | |
| TESTNODE_NITRO_CONTRACTS_VERSION: ${{ github.event_name == 'push' && 'all' || inputs.nitro-contracts-version }} | |
| run: >- | |
| node scripts/ci/resolve-testnode.mjs | |
| --name "$TESTNODE_NAME" | |
| --version "$TESTNODE_VERSION" | |
| --snapshot-version "$TESTNODE_SNAPSHOT_VERSION" | |
| --variant "$TESTNODE_VARIANT" | |
| --nitro-contracts-version "$TESTNODE_NITRO_CONTRACTS_VERSION" | |
| - name: Build publish matrix | |
| id: matrix | |
| env: | |
| INPUT_VARIANT: ${{ steps.resolve.outputs.variant }} | |
| INPUT_SNAPSHOT_VERSION: ${{ steps.resolve.outputs.snapshot-version }} | |
| INPUT_CONTRACTS_VERSION: ${{ steps.resolve.outputs.nitro-contracts-version }} | |
| run: >- | |
| node --input-type=module -e | |
| "import { NITRO_CONTRACTS_VERSIONS, VARIANTS, hasVariantSnapshot, resolveVariantSnapshot } from './packages/testnode/src/runtime.mjs'; | |
| const names = | |
| process.env.INPUT_VARIANT === 'all' | |
| ? Object.keys(VARIANTS) | |
| : [process.env.INPUT_VARIANT]; | |
| const contractsVersions = | |
| process.env.INPUT_CONTRACTS_VERSION === 'all' | |
| ? Object.keys(NITRO_CONTRACTS_VERSIONS) | |
| : [process.env.INPUT_CONTRACTS_VERSION]; | |
| const include = []; | |
| for (const variant of names) { | |
| const config = VARIANTS[variant]; | |
| if (!config) throw new Error(\`Unknown variant \${variant}\`); | |
| for (const contractsVersion of contractsVersions) { | |
| if (!hasVariantSnapshot(variant, contractsVersion)) { | |
| console.error(\`Skipping \${variant} x \${contractsVersion}: no snapshot bundle\`); | |
| continue; | |
| } | |
| const snapshot = resolveVariantSnapshot(variant, contractsVersion); | |
| include.push({ | |
| variant, | |
| contractsVersion, | |
| snapshotId: snapshot.snapshotId, | |
| snapshotReleaseTag: snapshot.snapshotReleaseTag | |
| }); | |
| } | |
| } | |
| const output = process.env.GITHUB_OUTPUT; | |
| if (!output) throw new Error('GITHUB_OUTPUT is required'); | |
| const { appendFileSync } = await import('node:fs'); | |
| appendFileSync(output, 'matrix=' + JSON.stringify({ include }) + '\\n');" | |
| publish-testnode-image: | |
| needs: resolve-publish-matrix | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJson(needs.resolve-publish-matrix.outputs.matrix) }} | |
| permissions: | |
| contents: read | |
| packages: write | |
| 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 | |
| # Install the pre-generated snapshot bundle for this variant. Snapshots are | |
| # generated out of band and published as release bundles (the per-variant | |
| # snapshotReleaseTag lives in runtime.mjs); the publish never runs init. | |
| - name: Install snapshot release | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TESTNODE_SNAPSHOT_GH_REPO: ${{ github.repository }} | |
| run: >- | |
| pnpm dev snapshot install --force | |
| --id "${{ matrix.snapshotId }}" | |
| --release-tag "${{ matrix.snapshotReleaseTag }}" | |
| - 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 }} |