Skip to content

Publish Docker Images #46

Publish Docker Images

Publish Docker Images #46

Workflow file for this run

# This workflow is based on https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
name: Publish Docker Images
on:
release:
types: [published]
workflow_dispatch:
inputs:
iota_node:
type: boolean
description: "Release iota-node image"
required: false
default: false
iota_indexer:
type: boolean
description: "Release iota-indexer image"
required: false
default: false
iota_tools:
type: boolean
description: "Release iota-tools image"
required: false
default: false
iota_graphql_rpc:
type: boolean
description: "Release iota-graphql-rpc image"
required: false
default: false
jobs:
prepare:
outputs:
images: ${{ steps.images.outputs.images }}
runs-on: ubuntu-24.04
steps:
- name: Define images to build
id: images
run: |
images_array=()
# Check iota_node: true if the input is set to true and the event is workflow_dispatch,
# or if the event is a release (in which case the job should run regardless of the input).
if [ "${{ github.event_name == 'workflow_dispatch' && github.event.inputs.iota_node == 'true' || github.event_name == 'release' }}" == "true" ]; then
images_array+=("iota-node")
fi
# Check iota_indexer: true if the input is set to true and the event is workflow_dispatch,
# or if the event is a release (in which case the job should run regardless of the input).
if [ "${{ github.event_name == 'workflow_dispatch' && github.event.inputs.iota_indexer == 'true' || github.event_name == 'release' }}" == "true" ]; then
images_array+=("iota-indexer")
fi
# Check iota_tools: true if the input is set to true and the event is workflow_dispatch,
# or if the event is a release (in which case the job should run regardless of the input).
if [ "${{ github.event_name == 'workflow_dispatch' && github.event.inputs.iota_tools == 'true' || github.event_name == 'release' }}" == "true" ]; then
images_array+=("iota-tools")
fi
# Check iota_graphql_rpc: true if the input is set to true and the event is workflow_dispatch,
# or if the event is a release (in which case the job should run regardless of the input).
if [ "${{ github.event_name == 'workflow_dispatch' && github.event.inputs.iota_graphql_rpc == 'true' || github.event_name == 'release' }}" == "true" ]; then
images_array+=("iota-graphql-rpc")
fi
# Check if the images_array is empty
if [ ${#images_array[@]} -eq 0 ]; then
echo "Error: images_array is empty"
exit 1
fi
echo "images=[$(printf '"%s",' "${images_array[@]}" | sed 's/,$//')]" >> "$GITHUB_OUTPUT"
build:
environment: release
needs: prepare
strategy:
fail-fast: false
matrix:
image: ${{ fromJSON(needs.prepare.outputs.images) }}
arch: [
amd64,
arm64
]
include:
- arch: amd64
os: ubuntu-24.04
- arch: arm64
os: ubuntu-24.04
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
- name: Prepare Environment Variables
run: |
echo "DOCKER_FILE=docker/${{ matrix.image }}/Dockerfile" >> $GITHUB_ENV
echo "DOCKER_IMAGE=iotaledger/${{ matrix.image }}" >> $GITHUB_ENV
echo "DOCKER_PLATFORM=linux/${{ matrix.arch }}" >> $GITHUB_ENV
echo "PLATFORM_PAIR=linux-${{ matrix.arch }}" >> $GITHUB_ENV
TOOLCHAIN_VERSION=$(grep -oE 'channel = "[^"]+' ./rust-toolchain.toml | sed 's/channel = "//')
echo "TOOLCHAIN_VERSION=${TOOLCHAIN_VERSION}" >> $GITHUB_ENV
echo "Rust toolchain version is ${{ env.TOOLCHAIN_VERSION }}"
echo "GIT_REVISION=$(git describe --always --abbrev=12 --dirty --exclude '*')" >> $GITHUB_ENV
echo "BUILD_DATE=$(date -u +'%Y-%m-%d')" >> $GITHUB_ENV
- name: Docker meta
id: meta
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1
with:
images: ${{ env.DOCKER_IMAGE }}
- name: Login to Docker Registry
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
username: ${{ secrets.DOCKER_REGISTRY_USERNAME }}
password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
registry: ${{ secrets.DOCKER_REGISTRY_URL }}
- name: Set up QEMU
if: ${{ matrix.arch == 'arm64' }}
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
- name: Build and push by digest
id: build-image
uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0
with:
context: .
file: ${{ env.DOCKER_FILE }}
platforms: ${{ env.DOCKER_PLATFORM }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,"name=${{ env.DOCKER_IMAGE }}",push-by-digest=true,name-canonical=true,push=true
build-args: |
GIT_REVISION=${{ env.GIT_REVISION }}
BUILD_DATE=${{ env.BUILD_DATE }}
RUST_IMAGE_VERSION=${{ env.TOOLCHAIN_VERSION }}-bookworm
- name: Export digest
run: |
mkdir -p ${{ runner.temp }}/digests
digest="${{ steps.build-image.outputs.digest }}"
touch "${{ runner.temp }}/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: digests-${{ github.sha }}-${{ matrix.image }}-${{ env.PLATFORM_PAIR }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1
tag:
environment: release # This will require a second approval after all `build` jobs have finished (see https://github.com/orgs/community/discussions/14417)
needs: [prepare, build]
strategy:
fail-fast: false
matrix:
image: ${{ fromJSON(needs.prepare.outputs.images) }}
runs-on: ubuntu-24.04
steps:
- name: Prepare Environment Variables
run: |
echo "DOCKER_IMAGE=iotaledger/${{ matrix.image }}" >> $GITHUB_ENV
- name: Download digests
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
path: ${{ runner.temp }}/digests
pattern: digests-${{ github.sha }}-${{ matrix.image }}-*
merge-multiple: true
- name: Login to Docker Registry
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
username: ${{ secrets.DOCKER_REGISTRY_USERNAME }}
password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
registry: ${{ secrets.DOCKER_REGISTRY_URL }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1
- name: Docker meta
id: meta
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1
with:
images: ${{ env.DOCKER_IMAGE }}
# mapping semver tags to networks
# v{MAJOR}.{MINOR}.{PATCH}-alpha -> alphanet
# v{MAJOR}.{MINOR}.{PATCH}-beta -> devnet
# v{MAJOR}.{MINOR}.{PATCH}-rc -> testnet
# v{MAJOR}.{MINOR}.{PATCH} -> mainnet
tags: |
type=raw,value={{sha}},enable=${{ github.event_name == 'workflow_dispatch' }}
type=raw,value={{tag}},enable=${{ github.event_name == 'release' }}
type=raw,value=alphanet,enable=${{ github.event_name == 'release' && contains(github.ref, '-alpha') }}
type=raw,value=devnet,enable=${{ github.event_name == 'release' && contains(github.ref, '-beta') }}
type=raw,value=testnet,enable=${{ github.event_name == 'release' && contains(github.ref, '-rc') }}
type=raw,value=mainnet,enable=${{ github.event_name == 'release' && !contains(github.ref, '-alpha') && !contains(github.ref, '-beta') && !contains(github.ref, '-rc') }}
type=raw,value=latest,enable=${{ github.event_name == 'release' && !contains(github.ref, '-alpha') && !contains(github.ref, '-beta') && !contains(github.ref, '-rc') }}
- name: Create manifest list and push
working-directory: ${{ runner.temp }}/digests
run: |
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
$(printf '${{ env.DOCKER_IMAGE }}@sha256:%s ' *)