mirror of
https://github.com/rustfs/rustfs.git
synced 2026-01-17 09:40:32 +00:00
The Docker workflow was not triggering for tag-based releases because it had 'branches: [main]' restriction in the workflow_run configuration. When pushing tags, the triggering workflow runs on the tag, not on main branch. Changes: - Remove 'branches: [main]' from workflow_run trigger - Simplify tag detection using github.event.workflow_run context instead of API calls - Use official workflow_run event properties (head_branch, event) for reliable detection - Support both 'refs/tags/VERSION' and direct 'VERSION' formats - Add better logging for debugging workflow trigger issues This fixes the issue where Docker images were not built for tagged releases.
418 lines
17 KiB
YAML
418 lines
17 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]
|
|
# 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 triggering workflow event and ref
|
|
triggering_event="${{ github.event.workflow_run.event }}"
|
|
head_branch="${{ github.event.workflow_run.head_branch }}"
|
|
|
|
echo "🔍 Analyzing triggering workflow:"
|
|
echo " 📋 Event: $triggering_event"
|
|
echo " 🌿 Head branch: $head_branch"
|
|
echo " 📎 Head SHA: ${{ github.event.workflow_run.head_sha }}"
|
|
|
|
# Check if this was triggered by a tag push
|
|
if [[ "$triggering_event" == "push" ]]; then
|
|
# For tag pushes, head_branch will be like "refs/tags/v1.0.0" or just "v1.0.0"
|
|
if [[ "$head_branch" == refs/tags/* ]]; then
|
|
# Extract tag name from refs/tags/TAG_NAME
|
|
tag_name="${head_branch#refs/tags/}"
|
|
version="$tag_name"
|
|
elif [[ "$head_branch" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+ ]]; then
|
|
# Direct tag name like "v1.0.0" or "1.0.0-alpha.1"
|
|
version="$head_branch"
|
|
elif [[ "$head_branch" == "main" ]]; then
|
|
# Regular branch push to main
|
|
build_type="development"
|
|
version="dev-${short_sha}"
|
|
should_build=false
|
|
echo "⏭️ Skipping Docker build for development version (main branch push)"
|
|
else
|
|
# Other branch push
|
|
build_type="development"
|
|
version="dev-${short_sha}"
|
|
should_build=false
|
|
echo "⏭️ Skipping Docker build for development version (branch: $head_branch)"
|
|
fi
|
|
|
|
# If we extracted a version (tag), determine release type
|
|
if [[ -n "$version" ]] && [[ "$version" != "dev-${short_sha}" ]]; then
|
|
# 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
|
|
fi
|
|
else
|
|
# Non-push events
|
|
build_type="development"
|
|
version="dev-${short_sha}"
|
|
should_build=false
|
|
echo "⏭️ Skipping Docker build for development version (event: $triggering_event)"
|
|
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
|