Feat/first nib images #28
Workflow file for this run
This file contains 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: Docker Build | |
on: | |
pull_request: | |
branches: [ main ] | |
paths-ignore: | |
- '**.md' | |
- '.github/**' | |
- '!.github/workflows/docker-build.yml' | |
permissions: | |
contents: read | |
packages: write | |
pull-requests: read | |
id-token: write | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: true | |
jobs: | |
detect-changes: | |
runs-on: ubuntu-latest | |
outputs: | |
base_matrix: ${{ steps.set-matrix.outputs.base_matrix }} | |
clients_matrix: ${{ steps.set-matrix.outputs.clients_matrix }} | |
protocols_matrix: ${{ steps.set-matrix.outputs.protocols_matrix }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Get changed files | |
id: changed-files | |
uses: tj-actions/changed-files@v40 | |
with: | |
files: | | |
** | |
- name: Generate build matrices | |
id: set-matrix | |
run: | | |
# Get list of changed files and filter to unique directories containing Dockerfile | |
CHANGED_DIRS=$(echo "${{ steps.changed-files.outputs.all_changed_files }}" | tr ' ' '\n' | while read -r file; do | |
dir=$(dirname "$file") | |
if [[ -f "$dir/Dockerfile" ]]; then | |
echo "$dir" | |
fi | |
done | sort -u) | |
# Create matrices using jq, filtering by directory structure | |
echo "base_matrix=$(echo "$CHANGED_DIRS" | grep "^node-base$" | jq -Rsc 'split("\n")[:-1] | {include: map({image_path: .})}')" >> $GITHUB_OUTPUT | |
echo "clients_matrix=$(echo "$CHANGED_DIRS" | grep "^clients/" | jq -Rsc 'split("\n")[:-1] | {include: map({image_path: .})}')" >> $GITHUB_OUTPUT | |
# Any directory that's not node-base or clients/ and contains a Dockerfile is a protocol | |
echo "protocols_matrix=$(echo "$CHANGED_DIRS" | grep -v "^node-base$" | grep -v "^clients/" | jq -Rsc 'split("\n")[:-1] | {include: map({image_path: .})}')" >> $GITHUB_OUTPUT | |
build-base: | |
needs: detect-changes | |
if: ${{ fromJson(needs.detect-changes.outputs.base_matrix).include[0] }} | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: ${{ fromJson(needs.detect-changes.outputs.base_matrix) }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Log in to GitHub Container Registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Generate version | |
id: version | |
run: | | |
SHA=$(git rev-parse --short HEAD) | |
echo "image_name=node-base" >> $GITHUB_OUTPUT | |
echo "image_tag=${SHA}" >> $GITHUB_OUTPUT | |
- name: Generate build contexts | |
id: build-contexts | |
run: | | |
# First, find all directories containing Dockerfiles to build our valid image list | |
VALID_IMAGES=$(find . -name Dockerfile -exec dirname {} \; | while read dir; do | |
# Convert directory path to image name (e.g., ./ethereum/ethereum-erigon -> ethereum-erigon) | |
basename "$dir" | tr '[:upper:]' '[:lower:]' | |
# For protocol directories, also add the protocol-client format | |
if [[ "$dir" =~ ^./[^/]+/[^/]+ ]]; then | |
echo "$dir" | sed 's|^./\([^/]\+\)/\([^/]\+\)|\1-\2|' | tr '[:upper:]' '[:lower:]' | |
fi | |
done | sort -u) | |
# Get the SHA for base images | |
SHA=$(git rev-parse --short HEAD) | |
# Now extract FROM directives and filter against our valid images | |
BUILD_CONTEXTS=$(grep -h "^FROM" ./${{ matrix.image_path }}/Dockerfile | while read -r line; do | |
# Extract image name and remove any tag/digest | |
image=$(echo "$line" | awk '{print $2}' | cut -d':' -f1 | cut -d'@' -f1) | |
# Check if this image is in our valid image list | |
if echo "$VALID_IMAGES" | grep -q "^${image}$"; then | |
# Always use SHA tag for base images | |
echo "${image}=ghcr.io/blockjoy/${image}:${SHA}" | |
fi | |
done | sort -u | tr '\n' ',' | sed 's/,$//') | |
echo "contexts=${BUILD_CONTEXTS}" >> $GITHUB_OUTPUT | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Build and push base image | |
uses: docker/build-push-action@v5 | |
with: | |
context: ./${{ matrix.image_path }} | |
push: true | |
build-args: | | |
GRAFANA_LOKI_API_KEY=${{ secrets.GRAFANA_LOKI_API_KEY }} | |
GRAFANA_PROM_API_KEY=${{ secrets.GRAFANA_PROM_API_KEY }} | |
build-contexts: ${{ steps.build-contexts.outputs.contexts }} | |
cache-from: type=gha | |
cache-to: type=gha,mode=max | |
tags: ghcr.io/blockjoy/${{ steps.version.outputs.image_name }}:${{ steps.version.outputs.image_tag }} | |
build-clients: | |
needs: [detect-changes, build-base] | |
if: | | |
always() && | |
needs.build-base.result != 'failure' && | |
fromJson(needs.detect-changes.outputs.clients_matrix).include[0] | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: ${{ fromJson(needs.detect-changes.outputs.clients_matrix) }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Log in to GitHub Container Registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Generate version | |
id: version | |
run: | | |
SHA=$(git rev-parse --short HEAD) | |
CLIENT_NAME=$(basename ${{ matrix.image_path }}) | |
IMAGE_NAME="blockjoy-${CLIENT_NAME}" | |
if [[ -f "${{ matrix.image_path }}/Dockerfile" ]]; then | |
CLIENT_VERSION=$(grep -E "ENV.*_VERSION=[[:space:]]*v?[0-9]+\.[0-9]+\.[0-9]+[-.a-zA-Z0-9]*" "${{ matrix.image_path }}/Dockerfile" | grep -oE "v?[0-9]+\.[0-9]+\.[0-9]+[-.a-zA-Z0-9]*") | |
if [[ ! -z "$CLIENT_VERSION" ]]; then | |
CLIENT_VERSION=${CLIENT_VERSION#v} | |
IMAGE_TAG="${CLIENT_VERSION}-${SHA}" | |
else | |
IMAGE_TAG="${SHA}" | |
fi | |
else | |
IMAGE_TAG="${SHA}" | |
fi | |
echo "image_name=${IMAGE_NAME}" >> $GITHUB_OUTPUT | |
echo "image_tag=${IMAGE_TAG}" >> $GITHUB_OUTPUT | |
- name: Generate build contexts | |
id: build-contexts | |
run: | | |
# First, find all directories containing Dockerfiles to build our valid image list | |
VALID_IMAGES=$(find . -name Dockerfile -exec dirname {} \; | while read dir; do | |
# Convert directory path to image name (e.g., ./ethereum/ethereum-erigon -> ethereum-erigon) | |
basename "$dir" | tr '[:upper:]' '[:lower:]' | |
# For protocol directories, also add the protocol-client format | |
if [[ "$dir" =~ ^./[^/]+/[^/]+ ]]; then | |
echo "$dir" | sed 's|^./\([^/]\+\)/\([^/]\+\)|\1-\2|' | tr '[:upper:]' '[:lower:]' | |
fi | |
done | sort -u) | |
# Get the SHA for base images | |
SHA=$(git rev-parse --short HEAD) | |
# Now extract FROM directives and filter against our valid images | |
BUILD_CONTEXTS=$(grep -h "^FROM" ./${{ matrix.image_path }}/Dockerfile | while read -r line; do | |
# Extract image name and remove any tag/digest | |
image=$(echo "$line" | awk '{print $2}' | cut -d':' -f1 | cut -d'@' -f1) | |
# Check if this image is in our valid image list | |
if echo "$VALID_IMAGES" | grep -q "^${image}$"; then | |
# Always use SHA tag for base images | |
echo "${image}=ghcr.io/blockjoy/${image}:${SHA}" | |
fi | |
done | sort -u | tr '\n' ',' | sed 's/,$//') | |
echo "contexts=${BUILD_CONTEXTS}" >> $GITHUB_OUTPUT | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Build and push client images | |
uses: docker/build-push-action@v5 | |
with: | |
context: ./${{ matrix.image_path }} | |
push: true | |
build-args: | | |
GRAFANA_LOKI_BASICAUTH=${{ secrets.GRAFANA_LOKI_BASICAUTH }} | |
GRAFANA_PROM_BASICAUTH=${{ secrets.GRAFANA_PROM_BASICAUTH }} | |
CLOUDFLARE_API_KEY=${{ secrets.CLOUDFLARE_API_KEY }} | |
build-contexts: ${{ steps.build-contexts.outputs.contexts }} | |
cache-from: type=gha | |
cache-to: type=gha,mode=max | |
tags: ghcr.io/blockjoy/${{ steps.version.outputs.image_name }}:${{ steps.version.outputs.image_tag }} | |
build-protocols: | |
needs: [detect-changes, build-clients] | |
if: | | |
always() && | |
needs.build-clients.result != 'failure' && | |
fromJson(needs.detect-changes.outputs.protocols_matrix).include[0] | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: ${{ fromJson(needs.detect-changes.outputs.protocols_matrix) }} | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Log in to GitHub Container Registry | |
uses: docker/login-action@v3 | |
with: | |
registry: ghcr.io | |
username: ${{ github.actor }} | |
password: ${{ secrets.GITHUB_TOKEN }} | |
- name: Generate version | |
id: version | |
run: | | |
SHA=$(git rev-parse --short HEAD) | |
IMAGE_NAME=$(basename $(dirname ${{ matrix.image_path }}))"-"$(basename ${{ matrix.image_path }}) | |
echo "image_name=${IMAGE_NAME}" >> $GITHUB_OUTPUT | |
echo "image_tag=${SHA}" >> $GITHUB_OUTPUT | |
- name: Generate build contexts | |
id: build-contexts | |
run: | | |
# First, find all directories containing Dockerfiles to build our valid image list | |
VALID_IMAGES=$(find . -name Dockerfile -exec dirname {} \; | while read dir; do | |
# Convert directory path to image name (e.g., ./ethereum/ethereum-erigon -> ethereum-erigon) | |
basename "$dir" | tr '[:upper:]' '[:lower:]' | |
# For protocol directories, also add the protocol-client format | |
if [[ "$dir" =~ ^./[^/]+/[^/]+ ]]; then | |
echo "$dir" | sed 's|^./\([^/]\+\)/\([^/]\+\)|\1-\2|' | tr '[:upper:]' '[:lower:]' | |
fi | |
done | sort -u) | |
# Get the SHA for base images | |
SHA=$(git rev-parse --short HEAD) | |
# Now extract FROM directives and filter against our valid images | |
BUILD_CONTEXTS=$(grep -h "^FROM" ./${{ matrix.image_path }}/Dockerfile | while read -r line; do | |
# Extract image name and remove any tag/digest | |
image=$(echo "$line" | awk '{print $2}' | cut -d':' -f1 | cut -d'@' -f1) | |
# Check if this image is in our valid image list | |
if echo "$VALID_IMAGES" | grep -q "^${image}$"; then | |
# Always use SHA tag for base images | |
echo "${image}=ghcr.io/blockjoy/${image}:${SHA}" | |
fi | |
done | sort -u | tr '\n' ',' | sed 's/,$//') | |
echo "contexts=${BUILD_CONTEXTS}" >> $GITHUB_OUTPUT | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v3 | |
- name: Build and push protocol images | |
uses: docker/build-push-action@v5 | |
with: | |
context: ./${{ matrix.image_path }} | |
push: true | |
build-args: | | |
GRAFANA_LOKI_BASICAUTH=${{ secrets.GRAFANA_LOKI_BASICAUTH }} | |
GRAFANA_PROM_BASICAUTH=${{ secrets.GRAFANA_PROM_BASICAUTH }} | |
CLOUDFLARE_API_KEY=${{ secrets.CLOUDFLARE_API_KEY }} | |
build-contexts: ${{ steps.build-contexts.outputs.contexts }} | |
cache-from: type=gha | |
cache-to: type=gha,mode=max | |
tags: ghcr.io/blockjoy/${{ steps.version.outputs.image_name }}:${{ steps.version.outputs.image_tag }} |