Skip to content

Build CSI Docker Image #39

Build CSI Docker Image

Build CSI Docker Image #39

name: Build CSI Docker Image
on:
push:
tags:
- 'v*'
paths:
- 'curvine-csi/**'
- 'curvine-cli/**'
- 'curvine-fuse/**'
- 'curvine-client/**'
- '.github/workflows/build-csi-image.yml'
workflow_dispatch:
inputs:
push_image:
description: 'Whether to push image to registries'
required: false
default: false
type: boolean
image_tag:
description: 'Image tag (e.g., latest, v1.0.0). Leave empty to use git tag.'
required: false
default: ''
type: string
platforms:
description: 'Target platforms (comma-separated)'
required: false
default: 'linux/amd64,linux/arm64'
type: string
permissions:
contents: read
packages: write
jobs:
# Prepare metadata shared across all jobs
prepare:
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.meta.outputs.tag }}
push_image: ${{ steps.meta.outputs.push_image }}
ghcr_image: ${{ steps.meta.outputs.ghcr_image }}
docker_image: ${{ steps.meta.outputs.docker_image }}
also_latest: ${{ steps.meta.outputs.also_latest }}
steps:
- name: Extract metadata for Docker
id: meta
run: |
# Determine tag: use git tag if triggered by push, otherwise use input or 'latest'
if [ "${{ github.event_name }}" == "push" ]; then
# Extract tag from ref (refs/tags/v1.0.0 -> v1.0.0)
TAG="${GITHUB_REF#refs/tags/}"
PUSH_IMAGE="true"
echo "Triggered by tag push: ${TAG}"
elif [ -n "${{ inputs.image_tag }}" ]; then
TAG="${{ inputs.image_tag }}"
PUSH_IMAGE="${{ inputs.push_image }}"
echo "Using manual tag: ${TAG}"
else
TAG="latest"
PUSH_IMAGE="${{ inputs.push_image }}"
echo "Using default tag: ${TAG}"
fi
echo "tag=${TAG}" >> $GITHUB_OUTPUT
echo "push_image=${PUSH_IMAGE}" >> $GITHUB_OUTPUT
# Generate image names for CSI
GHCR_IMAGE="ghcr.io/curvineio/curvine-csi"
DOCKER_IMAGE="curvine/curvine-csi"
echo "ghcr_image=${GHCR_IMAGE}" >> $GITHUB_OUTPUT
echo "docker_image=${DOCKER_IMAGE}" >> $GITHUB_OUTPUT
# Also tag as 'latest' if this is a version tag
if [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+ ]]; then
echo "also_latest=true" >> $GITHUB_OUTPUT
echo "Will also tag as 'latest'"
else
echo "also_latest=false" >> $GITHUB_OUTPUT
fi
# Build for each architecture on native runners
build-arch:
needs: prepare
strategy:
matrix:
include:
- arch: amd64
runner: ubuntu-latest
- arch: arm64
runner: ubuntu-24.04-arm
runs-on: ${{ matrix.runner }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
if: needs.prepare.outputs.push_image == 'true'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ secrets.GHCR_USERNAME }}
password: ${{ secrets.PAT_GITHUB_TOKEN }}
- name: Login to Docker Hub
if: needs.prepare.outputs.push_image == 'true'
uses: docker/login-action@v3
with:
username: curvine
password: ${{ secrets.PAT_DOCKERIO_TOKEN }}
- name: Build and push CSI image for ${{ matrix.arch }}
uses: docker/build-push-action@v5
with:
context: .
file: ./curvine-csi/Dockerfile
platforms: linux/${{ matrix.arch }}
push: ${{ needs.prepare.outputs.push_image == 'true' }}
tags: |
${{ needs.prepare.outputs.ghcr_image }}:${{ needs.prepare.outputs.tag }}-${{ matrix.arch }}
${{ needs.prepare.outputs.docker_image }}:${{ needs.prepare.outputs.tag }}-${{ matrix.arch }}
cache-from: type=gha,scope=${{ matrix.arch }}
cache-to: type=gha,mode=max,scope=${{ matrix.arch }}
shm-size: 2g
build-args: |
GOPROXY=https://goproxy.cn,direct
TARGETARCH=${{ matrix.arch }}
TARGETOS=linux
- name: Build summary for ${{ matrix.arch }}
run: |
echo "✅ Built CSI image for ${{ matrix.arch }} architecture" >> $GITHUB_STEP_SUMMARY
echo "Image: ${{ needs.prepare.outputs.ghcr_image }}:${{ needs.prepare.outputs.tag }}-${{ matrix.arch }}" >> $GITHUB_STEP_SUMMARY
# Create multi-arch manifest
create-manifest:
needs: [prepare, build-arch]
runs-on: ubuntu-latest
if: needs.prepare.outputs.push_image == 'true'
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ secrets.GHCR_USERNAME }}
password: ${{ secrets.PAT_GITHUB_TOKEN }}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: curvine
password: ${{ secrets.PAT_DOCKERIO_TOKEN }}
- name: Create and push multi-arch manifest for GHCR
run: |
# Create manifest for version tag
docker buildx imagetools create -t ${{ needs.prepare.outputs.ghcr_image }}:${{ needs.prepare.outputs.tag }} \
${{ needs.prepare.outputs.ghcr_image }}:${{ needs.prepare.outputs.tag }}-amd64 \
${{ needs.prepare.outputs.ghcr_image }}:${{ needs.prepare.outputs.tag }}-arm64
# Create manifest for latest tag if needed
if [ "${{ needs.prepare.outputs.also_latest }}" == "true" ]; then
docker buildx imagetools create -t ${{ needs.prepare.outputs.ghcr_image }}:latest \
${{ needs.prepare.outputs.ghcr_image }}:${{ needs.prepare.outputs.tag }}-amd64 \
${{ needs.prepare.outputs.ghcr_image }}:${{ needs.prepare.outputs.tag }}-arm64
fi
- name: Create and push multi-arch manifest for Docker Hub
run: |
# Create manifest for version tag
docker buildx imagetools create -t ${{ needs.prepare.outputs.docker_image }}:${{ needs.prepare.outputs.tag }} \
${{ needs.prepare.outputs.docker_image }}:${{ needs.prepare.outputs.tag }}-amd64 \
${{ needs.prepare.outputs.docker_image }}:${{ needs.prepare.outputs.tag }}-arm64
# Create manifest for latest tag if needed
if [ "${{ needs.prepare.outputs.also_latest }}" == "true" ]; then
docker buildx imagetools create -t ${{ needs.prepare.outputs.docker_image }}:latest \
${{ needs.prepare.outputs.docker_image }}:${{ needs.prepare.outputs.tag }}-amd64 \
${{ needs.prepare.outputs.docker_image }}:${{ needs.prepare.outputs.tag }}-arm64
fi
- name: Manifest creation summary
run: |
echo "### Multi-arch Manifest Created 🎉" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Combined architectures:** amd64, arm64" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Manifests created:**" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ needs.prepare.outputs.ghcr_image }}:${{ needs.prepare.outputs.tag }}\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ needs.prepare.outputs.docker_image }}:${{ needs.prepare.outputs.tag }}\`" >> $GITHUB_STEP_SUMMARY
if [ "${{ needs.prepare.outputs.also_latest }}" == "true" ]; then
echo "- \`${{ needs.prepare.outputs.ghcr_image }}:latest\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ needs.prepare.outputs.docker_image }}:latest\`" >> $GITHUB_STEP_SUMMARY
fi
# Final summary
summary:
needs: [prepare, build-arch, create-manifest]
runs-on: ubuntu-latest
if: always()
steps:
- name: Final build summary
run: |
echo "### CSI Image Build Summary 🚀" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Platform:** Rocky Linux 9" >> $GITHUB_STEP_SUMMARY
echo "**Architectures:** amd64 (native), arm64 (native)" >> $GITHUB_STEP_SUMMARY
echo "**Tag:** ${{ needs.prepare.outputs.tag }}" >> $GITHUB_STEP_SUMMARY
echo "**Trigger:** ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
echo "**Components:** csi, curvine-cli, curvine-fuse" >> $GITHUB_STEP_SUMMARY
echo "**Build Strategy:** Native runners for each architecture" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ needs.prepare.outputs.push_image }}" == "true" ]; then
echo "**Multi-arch images pushed to:**" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ needs.prepare.outputs.ghcr_image }}:${{ needs.prepare.outputs.tag }}\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ needs.prepare.outputs.docker_image }}:${{ needs.prepare.outputs.tag }}\`" >> $GITHUB_STEP_SUMMARY
if [ "${{ needs.prepare.outputs.also_latest }}" == "true" ]; then
echo "- \`${{ needs.prepare.outputs.ghcr_image }}:latest\`" >> $GITHUB_STEP_SUMMARY
echo "- \`${{ needs.prepare.outputs.docker_image }}:latest\`" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Pull commands:**" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "# Pull from GitHub Container Registry" >> $GITHUB_STEP_SUMMARY
echo "docker pull ${{ needs.prepare.outputs.ghcr_image }}:${{ needs.prepare.outputs.tag }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "# Pull from Docker Hub" >> $GITHUB_STEP_SUMMARY
echo "docker pull ${{ needs.prepare.outputs.docker_image }}:${{ needs.prepare.outputs.tag }}" >> $GITHUB_STEP_SUMMARY
if [ "${{ needs.prepare.outputs.also_latest }}" == "true" ]; then
echo "" >> $GITHUB_STEP_SUMMARY
echo "# Pull latest version" >> $GITHUB_STEP_SUMMARY
echo "docker pull ${{ needs.prepare.outputs.ghcr_image }}:latest" >> $GITHUB_STEP_SUMMARY
echo "docker pull ${{ needs.prepare.outputs.docker_image }}:latest" >> $GITHUB_STEP_SUMMARY
fi
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Verify multi-arch:**" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "docker buildx imagetools inspect ${{ needs.prepare.outputs.ghcr_image }}:${{ needs.prepare.outputs.tag }}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Deploy with Helm:**" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
echo "helm install curvine-csi ./curvine-csi/helm \\" >> $GITHUB_STEP_SUMMARY
echo " --set image.repository=${{ needs.prepare.outputs.ghcr_image }} \\" >> $GITHUB_STEP_SUMMARY
echo " --set image.tag=${{ needs.prepare.outputs.tag }}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
else
echo "**Note:** Image was built but not pushed (push_image=false)" >> $GITHUB_STEP_SUMMARY
fi