mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 16:28:15 +00:00
55b84262b5
- Replace git commands with GitHub API calls for tag detection - Add proper commit checkout for workflow_run events - Use gh CLI and curl fallback for better reliability - Add debug output to help troubleshoot tag detection issues This should fix the issue where Docker builds were not triggered for tagged releases due to missing tag information in the workflow_run environment.
403 lines
16 KiB
YAML
403 lines
16 KiB
YAML
# Copyright 2024 RustFS Team
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
# Docker Images Workflow
|
|
#
|
|
# This workflow builds Docker images using pre-built binaries from the build workflow.
|
|
#
|
|
# Trigger Types:
|
|
# 1. workflow_run: Automatically triggered when "Build and Release" workflow completes
|
|
# 2. workflow_dispatch: Manual trigger for standalone Docker builds
|
|
#
|
|
# Key Features:
|
|
# - Only triggers when Linux builds (x86_64 + aarch64) are successful
|
|
# - Independent of macOS/Windows build status
|
|
# - Uses workflow_run event for precise control
|
|
# - Only builds Docker images for releases and prereleases (development builds are skipped)
|
|
|
|
name: Docker Images
|
|
|
|
# Permissions needed for workflow_run event and Docker registry access
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
|
|
on:
|
|
# Automatically triggered when build workflow completes
|
|
workflow_run:
|
|
workflows: ["Build and Release"]
|
|
types: [completed]
|
|
branches: [main]
|
|
# Manual trigger with same parameters for consistency
|
|
workflow_dispatch:
|
|
inputs:
|
|
push_images:
|
|
description: "Push images to registries"
|
|
required: false
|
|
default: true
|
|
type: boolean
|
|
version:
|
|
description: "Version to build (latest for stable release, or specific version like v1.0.0, v1.0.0-alpha1)"
|
|
required: false
|
|
default: "latest"
|
|
type: string
|
|
force_rebuild:
|
|
description: "Force rebuild even if binary exists (useful for testing)"
|
|
required: false
|
|
default: false
|
|
type: boolean
|
|
|
|
env:
|
|
DOCKERHUB_USERNAME: rustfs
|
|
CARGO_TERM_COLOR: always
|
|
REGISTRY_DOCKERHUB: rustfs/rustfs
|
|
REGISTRY_GHCR: ghcr.io/${{ github.repository }}
|
|
DOCKER_PLATFORMS: linux/amd64,linux/arm64
|
|
|
|
jobs:
|
|
# Check if we should build Docker images
|
|
build-check:
|
|
name: Docker Build Check
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
should_build: ${{ steps.check.outputs.should_build }}
|
|
should_push: ${{ steps.check.outputs.should_push }}
|
|
build_type: ${{ steps.check.outputs.build_type }}
|
|
version: ${{ steps.check.outputs.version }}
|
|
short_sha: ${{ steps.check.outputs.short_sha }}
|
|
is_prerelease: ${{ steps.check.outputs.is_prerelease }}
|
|
create_latest: ${{ steps.check.outputs.create_latest }}
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
# For workflow_run events, checkout the specific commit that triggered the workflow
|
|
ref: ${{ github.event.workflow_run.head_sha || github.sha }}
|
|
|
|
- name: Check build conditions
|
|
id: check
|
|
run: |
|
|
should_build=false
|
|
should_push=false
|
|
build_type="none"
|
|
version=""
|
|
short_sha=""
|
|
is_prerelease=false
|
|
create_latest=false
|
|
|
|
if [[ "${{ github.event_name }}" == "workflow_run" ]]; then
|
|
# Triggered by build workflow completion
|
|
echo "🔗 Triggered by build workflow completion"
|
|
|
|
# Check if the triggering workflow was successful
|
|
# If the workflow succeeded, it means ALL builds (including Linux x86_64 and aarch64) succeeded
|
|
if [[ "${{ github.event.workflow_run.conclusion }}" == "success" ]]; then
|
|
echo "✅ Build workflow succeeded, all builds including Linux are successful"
|
|
should_build=true
|
|
should_push=true
|
|
else
|
|
echo "❌ Build workflow failed (conclusion: ${{ github.event.workflow_run.conclusion }}), skipping Docker build"
|
|
should_build=false
|
|
fi
|
|
|
|
# Extract version info from commit message or use commit SHA
|
|
# Use Git to generate consistent short SHA (ensures uniqueness like build.yml)
|
|
short_sha=$(git rev-parse --short "${{ github.event.workflow_run.head_sha }}")
|
|
|
|
# Determine build type based on GitHub releases
|
|
# Use GitHub API to check if this commit has a release/tag
|
|
echo "🔍 Checking for releases/tags on commit ${{ github.event.workflow_run.head_sha }}"
|
|
|
|
# Get all tags for this repository and check if any point to this commit
|
|
GITHUB_API_URL="https://api.github.com/repos/${{ github.repository }}/tags"
|
|
|
|
# Use curl to get tags (more reliable than git in workflow_run context)
|
|
if command -v gh >/dev/null 2>&1; then
|
|
# Use GitHub CLI if available
|
|
tag_info=$(gh api repos/${{ github.repository }}/tags --jq '.[] | select(.commit.sha == "${{ github.event.workflow_run.head_sha }}") | .name' | head -n1)
|
|
else
|
|
# Fallback to curl
|
|
tag_info=$(curl -s "$GITHUB_API_URL" | jq -r '.[] | select(.commit.sha == "${{ github.event.workflow_run.head_sha }}") | .name' | head -n1)
|
|
fi
|
|
|
|
if [[ -n "$tag_info" ]] && [[ "$tag_info" != "null" ]]; then
|
|
# This commit has a tag, treat as release build
|
|
version="$tag_info"
|
|
# Remove 'v' prefix if present for consistent version format
|
|
if [[ "$version" == v* ]]; then
|
|
version="${version#v}"
|
|
fi
|
|
|
|
if [[ "$version" == *"alpha"* ]] || [[ "$version" == *"beta"* ]] || [[ "$version" == *"rc"* ]]; then
|
|
build_type="prerelease"
|
|
is_prerelease=true
|
|
echo "🧪 Building Docker image for prerelease: $version"
|
|
else
|
|
build_type="release"
|
|
create_latest=true
|
|
echo "🚀 Building Docker image for release: $version"
|
|
fi
|
|
else
|
|
# No tag found, treat as development build
|
|
build_type="development"
|
|
version="dev-${short_sha}"
|
|
should_build=false
|
|
echo "⏭️ Skipping Docker build for development version (no tag found)"
|
|
echo "🔍 Debug: Checked commit ${{ github.event.workflow_run.head_sha }} for tags"
|
|
fi
|
|
|
|
echo "🔄 Build triggered by workflow_run:"
|
|
echo " 📋 Conclusion: ${{ github.event.workflow_run.conclusion }}"
|
|
echo " 🌿 Branch: ${{ github.event.workflow_run.head_branch }}"
|
|
echo " 📎 SHA: ${{ github.event.workflow_run.head_sha }}"
|
|
echo " 🎯 Event: ${{ github.event.workflow_run.event }}"
|
|
|
|
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
|
# Manual trigger
|
|
input_version="${{ github.event.inputs.version }}"
|
|
version="${input_version}"
|
|
should_push="${{ github.event.inputs.push_images }}"
|
|
should_build=true
|
|
|
|
# Get short SHA
|
|
short_sha=$(git rev-parse --short HEAD)
|
|
|
|
echo "🎯 Manual Docker build triggered:"
|
|
echo " 📋 Requested version: $input_version"
|
|
echo " 🔧 Force rebuild: ${{ github.event.inputs.force_rebuild }}"
|
|
echo " 🚀 Push images: $should_push"
|
|
|
|
case "$input_version" in
|
|
"latest")
|
|
build_type="release"
|
|
create_latest=true
|
|
echo "🚀 Building with latest stable release version"
|
|
;;
|
|
# Prerelease versions (must match first, more specific)
|
|
v*alpha*|v*beta*|v*rc*|*alpha*|*beta*|*rc*)
|
|
build_type="prerelease"
|
|
is_prerelease=true
|
|
echo "🧪 Building with prerelease version: $input_version"
|
|
;;
|
|
# Release versions (match after prereleases, more general)
|
|
v[0-9]*|[0-9]*.*.*)
|
|
build_type="release"
|
|
create_latest=true
|
|
echo "📦 Building with specific release version: $input_version"
|
|
;;
|
|
*)
|
|
# Invalid version for Docker build
|
|
should_build=false
|
|
echo "❌ Invalid version for Docker build: $input_version"
|
|
echo "⚠️ Only release versions (latest, v1.0.0, 1.0.0) and prereleases (v1.0.0-alpha1, 1.0.0-beta2) are supported"
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
echo "should_build=$should_build" >> $GITHUB_OUTPUT
|
|
echo "should_push=$should_push" >> $GITHUB_OUTPUT
|
|
echo "build_type=$build_type" >> $GITHUB_OUTPUT
|
|
echo "version=$version" >> $GITHUB_OUTPUT
|
|
echo "short_sha=$short_sha" >> $GITHUB_OUTPUT
|
|
echo "is_prerelease=$is_prerelease" >> $GITHUB_OUTPUT
|
|
echo "create_latest=$create_latest" >> $GITHUB_OUTPUT
|
|
|
|
echo "🐳 Docker Build Summary:"
|
|
echo " - Should build: $should_build"
|
|
echo " - Should push: $should_push"
|
|
echo " - Build type: $build_type"
|
|
echo " - Version: $version"
|
|
echo " - Short SHA: $short_sha"
|
|
echo " - Is prerelease: $is_prerelease"
|
|
echo " - Create latest: $create_latest"
|
|
|
|
# Build multi-arch Docker images
|
|
# Strategy: Build images using pre-built binaries from dl.rustfs.com
|
|
# Supports both release and dev channel binaries based on build context
|
|
# Only runs when should_build is true (which includes workflow success check)
|
|
build-docker:
|
|
name: Build Docker Images
|
|
needs: build-check
|
|
if: needs.build-check.outputs.should_build == 'true'
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 60
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Login to Docker Hub
|
|
uses: docker/login-action@v3
|
|
with:
|
|
username: ${{ env.DOCKERHUB_USERNAME }}
|
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
|
|
# - name: Login to GitHub Container Registry
|
|
# uses: docker/login-action@v3
|
|
# with:
|
|
# registry: ghcr.io
|
|
# username: ${{ github.actor }}
|
|
# password: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Set up QEMU
|
|
uses: docker/setup-qemu-action@v3
|
|
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
|
|
- name: Extract metadata and generate tags
|
|
id: meta
|
|
run: |
|
|
BUILD_TYPE="${{ needs.build-check.outputs.build_type }}"
|
|
VERSION="${{ needs.build-check.outputs.version }}"
|
|
SHORT_SHA="${{ needs.build-check.outputs.short_sha }}"
|
|
CREATE_LATEST="${{ needs.build-check.outputs.create_latest }}"
|
|
|
|
# Convert version format for Dockerfile compatibility
|
|
case "$VERSION" in
|
|
"latest")
|
|
# For stable latest, use RELEASE=latest + release CHANNEL
|
|
DOCKER_RELEASE="latest"
|
|
DOCKER_CHANNEL="release"
|
|
;;
|
|
v*)
|
|
# For versioned releases (v1.0.0), remove 'v' prefix for Dockerfile
|
|
DOCKER_RELEASE="${VERSION#v}"
|
|
DOCKER_CHANNEL="release"
|
|
;;
|
|
*)
|
|
# For other versions, pass as-is
|
|
DOCKER_RELEASE="${VERSION}"
|
|
DOCKER_CHANNEL="release"
|
|
;;
|
|
esac
|
|
|
|
echo "docker_release=$DOCKER_RELEASE" >> $GITHUB_OUTPUT
|
|
echo "docker_channel=$DOCKER_CHANNEL" >> $GITHUB_OUTPUT
|
|
|
|
echo "🐳 Docker build parameters:"
|
|
echo " - Original version: $VERSION"
|
|
echo " - Docker RELEASE: $DOCKER_RELEASE"
|
|
echo " - Docker CHANNEL: $DOCKER_CHANNEL"
|
|
|
|
# Generate tags based on build type
|
|
# Only support release and prerelease builds (no development builds)
|
|
TAGS="${{ env.REGISTRY_DOCKERHUB }}:${VERSION}"
|
|
|
|
# Add channel tags for prereleases and latest for stable
|
|
if [[ "$CREATE_LATEST" == "true" ]]; then
|
|
# Stable release
|
|
TAGS="$TAGS,${{ env.REGISTRY_DOCKERHUB }}:latest"
|
|
elif [[ "$BUILD_TYPE" == "prerelease" ]]; then
|
|
# Prerelease channel tags (alpha, beta, rc)
|
|
if [[ "$VERSION" == *"alpha"* ]]; then
|
|
CHANNEL="alpha"
|
|
elif [[ "$VERSION" == *"beta"* ]]; then
|
|
CHANNEL="beta"
|
|
elif [[ "$VERSION" == *"rc"* ]]; then
|
|
CHANNEL="rc"
|
|
fi
|
|
|
|
if [[ -n "$CHANNEL" ]]; then
|
|
TAGS="$TAGS,${{ env.REGISTRY_DOCKERHUB }}:${CHANNEL}"
|
|
fi
|
|
fi
|
|
|
|
# Output tags
|
|
echo "tags=$TAGS" >> $GITHUB_OUTPUT
|
|
|
|
# Generate labels
|
|
LABELS="org.opencontainers.image.title=RustFS"
|
|
LABELS="$LABELS,org.opencontainers.image.description=RustFS distributed object storage system"
|
|
LABELS="$LABELS,org.opencontainers.image.version=$VERSION"
|
|
LABELS="$LABELS,org.opencontainers.image.revision=${{ github.sha }}"
|
|
LABELS="$LABELS,org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}"
|
|
LABELS="$LABELS,org.opencontainers.image.created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
|
|
LABELS="$LABELS,org.opencontainers.image.build-type=$BUILD_TYPE"
|
|
|
|
echo "labels=$LABELS" >> $GITHUB_OUTPUT
|
|
|
|
echo "🐳 Generated Docker tags:"
|
|
echo "$TAGS" | tr ',' '\n' | sed 's/^/ - /'
|
|
echo "📋 Build type: $BUILD_TYPE"
|
|
echo "🔖 Version: $VERSION"
|
|
|
|
- name: Build and push Docker image
|
|
uses: docker/build-push-action@v6
|
|
with:
|
|
context: .
|
|
file: Dockerfile
|
|
platforms: ${{ env.DOCKER_PLATFORMS }}
|
|
push: ${{ needs.build-check.outputs.should_push == 'true' }}
|
|
tags: ${{ steps.meta.outputs.tags }}
|
|
labels: ${{ steps.meta.outputs.labels }}
|
|
cache-from: |
|
|
type=gha,scope=docker-binary
|
|
cache-to: |
|
|
type=gha,mode=max,scope=docker-binary
|
|
build-args: |
|
|
BUILDTIME=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
|
|
VERSION=${{ needs.build-check.outputs.version }}
|
|
BUILD_TYPE=${{ needs.build-check.outputs.build_type }}
|
|
REVISION=${{ github.sha }}
|
|
RELEASE=${{ steps.meta.outputs.docker_release }}
|
|
CHANNEL=${{ steps.meta.outputs.docker_channel }}
|
|
BUILDKIT_INLINE_CACHE=1
|
|
# Enable advanced BuildKit features for better performance
|
|
provenance: false
|
|
sbom: false
|
|
# Add retry mechanism by splitting the build process
|
|
no-cache: false
|
|
pull: true
|
|
|
|
# Note: Manifest creation is no longer needed as we only build one variant
|
|
# Multi-arch manifests are automatically created by docker/build-push-action
|
|
|
|
# Docker build summary
|
|
docker-summary:
|
|
name: Docker Build Summary
|
|
needs: [build-check, build-docker]
|
|
if: always() && needs.build-check.outputs.should_build == 'true'
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Docker build completion summary
|
|
run: |
|
|
BUILD_TYPE="${{ needs.build-check.outputs.build_type }}"
|
|
VERSION="${{ needs.build-check.outputs.version }}"
|
|
CREATE_LATEST="${{ needs.build-check.outputs.create_latest }}"
|
|
|
|
echo "🐳 Docker build completed successfully!"
|
|
echo "📦 Build type: $BUILD_TYPE"
|
|
echo "🔢 Version: $VERSION"
|
|
echo "🚀 Strategy: Images using pre-built binaries (release channel only)"
|
|
echo ""
|
|
|
|
case "$BUILD_TYPE" in
|
|
"release")
|
|
echo "🚀 Release Docker image has been built with ${VERSION} tags"
|
|
echo "✅ This image is ready for production use"
|
|
if [[ "$CREATE_LATEST" == "true" ]]; then
|
|
echo "🏷️ Latest tag has been created for stable release"
|
|
fi
|
|
;;
|
|
"prerelease")
|
|
echo "🧪 Prerelease Docker image has been built with ${VERSION} tags"
|
|
echo "⚠️ This is a prerelease image - use with caution"
|
|
echo "🚫 Latest tag NOT created for prerelease"
|
|
;;
|
|
*)
|
|
echo "❌ Unexpected build type: $BUILD_TYPE"
|
|
;;
|
|
esac
|