diff --git a/.github/workflows/sf_release.yml b/.github/workflows/sf_release.yml index 5608b9b36a..8fe0ea4f51 100644 --- a/.github/workflows/sf_release.yml +++ b/.github/workflows/sf_release.yml @@ -16,13 +16,50 @@ on: env: REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} FIREHOSE_ETHEREUM_IMAGE: ${{ inputs.firehose_ethereum_image || 'ghcr.io/streamingfast/firehose-ethereum:latest' }} jobs: - push: - name: Docker build & push + prepare: + name: Resolve versions runs-on: ubuntu-24.04 + outputs: + version: ${{ steps.extract-versions.outputs.VERSION }} + fireeth_docker_suffix: ${{ steps.extract-versions.outputs.FIREETH_DOCKER_SUFFIX }} + image_name: ${{ steps.image.outputs.name }} + steps: + - name: Lowercase image name + id: image + # Container registries require lowercase repository names; github.repository + # preserves the org's original casing, so normalize it here. + run: echo "name=${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT" + + - name: Extract versions + id: extract-versions + run: | + version="edge-${GITHUB_SHA::7}" + if [[ "${GITHUB_REF}" == refs/tags/* ]]; then + version=${GITHUB_REF#refs/tags/} + fi + + docker pull "${{ env.FIREHOSE_ETHEREUM_IMAGE }}" + fireeth_version=$(docker inspect "${{ env.FIREHOSE_ETHEREUM_IMAGE }}" --format='{{index .Config.Labels "org.opencontainers.image.version"}}') + + echo "VERSION=${version}" >> "$GITHUB_OUTPUT" + echo "FIREETH_VERSION=${fireeth_version}" >> "$GITHUB_OUTPUT" + echo "FIREETH_DOCKER_SUFFIX=${version}-fireeth-${fireeth_version}" >> "$GITHUB_OUTPUT" + + build: + name: Build & push (${{ matrix.arch }}) + needs: prepare + strategy: + fail-fast: false + matrix: + include: + - arch: amd64 + runner: ubuntu-24.04 + - arch: arm64 + runner: ubuntu-24.04-arm + runs-on: ${{ matrix.runner }} permissions: contents: read packages: write @@ -61,73 +98,100 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract versions - id: extract-versions - run: | - version="edge-${GITHUB_SHA::7}" - if [[ "${GITHUB_REF}" == refs/tags/* ]]; then - version=${GITHUB_REF#refs/tags/} - fi - - docker pull "${{ env.FIREHOSE_ETHEREUM_IMAGE }}" - fireeth_version=$(docker inspect "${{ env.FIREHOSE_ETHEREUM_IMAGE }}" --format='{{index .Config.Labels "org.opencontainers.image.version"}}') - - echo "VERSION=${version}" >> "$GITHUB_OUTPUT" - echo "FIREETH_VERSION=${fireeth_version}" >> "$GITHUB_OUTPUT" - echo "FIREETH_DOCKER_SUFFIX=${version}-fireeth-${fireeth_version}" >> "$GITHUB_OUTPUT" - - - name: Generate docker tags/labels from github build context + - name: Generate docker labels from github build context id: meta-bare uses: docker/metadata-action@v5 with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | - type=ref,event=tag - type=sha,prefix= - type=raw,value=${{ steps.extract-versions.outputs.VERSION }} - type=raw,value=${{ steps.extract-versions.outputs.VERSION }},suffix=${{ steps.extract-versions.outputs.FIREETH_DOCKER_SUFFIX }} - type=raw,enable=${{ github.ref == 'refs/heads/develop' }},value=develop + images: ${{ env.REGISTRY }}/${{ needs.prepare.outputs.image_name }} - - name: Build and push nitro Docker image + - name: Build nitro Docker image uses: docker/build-push-action@v6 with: context: . target: nitro-node file: ./Dockerfile push: false - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-base:${{ steps.extract-versions.outputs.VERSION }} + tags: ${{ env.REGISTRY }}/${{ needs.prepare.outputs.image_name }}-base:${{ needs.prepare.outputs.version }} labels: ${{ steps.meta-bare.outputs.labels }} - - name: Build and push final (fireeth + nitro) Docker image + - name: Build and push final (fireeth + nitro) per-arch image uses: docker/build-push-action@v6 with: context: . file: ./Dockerfile.sf push: true build-args: | - NITRO_BASE_IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-base:${{ steps.extract-versions.outputs.VERSION }} + NITRO_BASE_IMAGE=${{ env.REGISTRY }}/${{ needs.prepare.outputs.image_name }}-base:${{ needs.prepare.outputs.version }} FIREHOSE_ETHEREUM_IMAGE=${{ env.FIREHOSE_ETHEREUM_IMAGE }} - tags: ${{ steps.meta-bare.outputs.tags }} + tags: ${{ env.REGISTRY }}/${{ needs.prepare.outputs.image_name }}:${{ needs.prepare.outputs.version }}-${{ matrix.arch }} labels: ${{ steps.meta-bare.outputs.labels }} + manifest: + name: Create multi-arch manifests + needs: [prepare, build] + runs-on: ubuntu-24.04 + permissions: + contents: read + packages: write + + steps: + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Generate docker tags from github build context + id: meta-bare + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ needs.prepare.outputs.image_name }} + tags: | + type=ref,event=tag + type=sha,prefix= + type=raw,value=${{ needs.prepare.outputs.version }} + type=raw,value=${{ needs.prepare.outputs.version }},suffix=${{ needs.prepare.outputs.fireeth_docker_suffix }} + type=raw,enable=${{ github.ref == 'refs/heads/develop' }},value=develop + + - name: Create and push manifests + env: + IMAGE_NAME: ${{ needs.prepare.outputs.image_name }} + VERSION: ${{ needs.prepare.outputs.version }} + TAGS: ${{ steps.meta-bare.outputs.tags }} + run: | + src_prefix="${REGISTRY}/${IMAGE_NAME}:${VERSION}" + while IFS= read -r tag; do + [ -n "$tag" ] || continue + docker buildx imagetools create -t "$tag" \ + "${src_prefix}-amd64" "${src_prefix}-arm64" + done <<< "$TAGS" + release: if: startsWith(github.ref, 'refs/tags/') - needs: push + needs: [prepare, manifest] runs-on: ubuntu-24.04 permissions: contents: write + packages: read steps: - - name: Extract image - id: image - run: | - # The run is done only on tags, so we can ref/tags/ replace directly here - echo "ID=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + - name: Log in to the Container registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract assets + - name: Extract binaries + env: + IMAGE_NAME: ${{ needs.prepare.outputs.image_name }} + VERSION: ${{ needs.prepare.outputs.version }} run: | - # The --platform are not really needed here, but it removes the warning - docker cp $(docker create --platform=linux/amd64 ${{ steps.image.outputs.ID }}):/usr/local/bin/nitro ./nitro_linux_amd64 + for arch in amd64 arm64; do + src="${REGISTRY}/${IMAGE_NAME}:${VERSION}-${arch}" + docker cp "$(docker create "$src"):/usr/local/bin/nitro" "./nitro_linux_${arch}" + done - name: Extract Changelog id: changelog @@ -146,3 +210,4 @@ jobs: prerelease: ${{ contains(github.ref, 'beta') || contains(github.ref, 'rc') }} files: | ./nitro_linux_amd64 + ./nitro_linux_arm64 diff --git a/Makefile b/Makefile index 405082497d..15b960c69c 100644 --- a/Makefile +++ b/Makefile @@ -364,8 +364,8 @@ endef docker: @$(resolve_gh_token_and_secret); \ for t in nitro-node-slim nitro-node nitro-node-dev; do \ - echo "+ docker build $$SECRET -t $$t --target $$t ."; \ - docker build $$SECRET -t "$$t" --target "$$t" . || exit 1; \ + echo "+ docker build $$SECRET --platform $(ARCH) -t $$t --target $$t ."; \ + docker build $$SECRET --platform "$(ARCH)" -t "$$t" --target "$$t" . || exit 1; \ done .PHONY: docker-machine-versions ## Build Docker image for machine versions. @@ -762,3 +762,5 @@ contracts/test/prover/proofs/%.json: $(arbitrator_cases)/%.wasm $(prover_bin) always: # use this to force other rules to always build .DELETE_ON_ERROR: # causes a failure to delete its target + +ARCH ?= linux/amd64