AI-Infra-Guard / .github /workflows /docker-publish.yml
AbdulElahGwaith's picture
Upload folder using huggingface_hub
ffb6330 verified
name: 🐳 Build and Push Docker Images
on:
push:
tags:
- v*
workflow_dispatch:
inputs:
tag:
description: '手动指定标签版本 (例如: v1.0.0, dev, test, staging)'
required: true
type: string
force_build:
description: '强制构建 (即使标签不存在)'
required: false
type: boolean
default: false
env:
REGISTRY: docker.io
IMAGE_NAME_SERVER: zhuquelab/aig-server
IMAGE_NAME_AGENT: zhuquelab/aig-agent
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: 🛒 Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 🏷️ Validate and setup tag
id: tag-setup
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
# 手动触发时的标签处理
INPUT_TAG="${{ github.event.inputs.tag }}"
FORCE_BUILD="${{ github.event.inputs.force_build }}"
echo "手动触发构建,指定标签: $INPUT_TAG"
# 简化的标签格式验证
# 支持更灵活的标签格式
if [[ "$INPUT_TAG" =~ ^v[0-9]+(\.[0-9]+)*(-[a-zA-Z0-9]+)*(\+[a-zA-Z0-9]+)*$ ]]; then
echo "✅ 检测到语义版本标签: $INPUT_TAG"
TAG_TYPE="semantic"
elif [[ "$INPUT_TAG" =~ ^[a-zA-Z0-9][a-zA-Z0-9._-]*$ ]]; then
echo "✅ 检测到自定义标签: $INPUT_TAG"
TAG_TYPE="custom"
else
echo "⚠️ 警告: 标签格式可能不规范,但将继续构建: $INPUT_TAG"
TAG_TYPE="custom"
fi
# 检查标签是否存在并处理
if git tag -l | grep -q "^$INPUT_TAG$"; then
echo "✅ 标签 $INPUT_TAG 存在于仓库中"
# 切换到指定标签
git checkout $INPUT_TAG
elif [ "$TAG_TYPE" = "custom" ]; then
echo "ℹ️ 自定义标签 $INPUT_TAG 不存在于仓库中"
echo "将基于当前分支构建自定义版本镜像"
# 自定义标签默认允许基于当前代码构建
elif [ "$FORCE_BUILD" = "true" ]; then
echo "⚠️ 警告: 语义版本标签 $INPUT_TAG 不存在,但启用了强制构建"
echo "将基于当前分支构建,但使用指定的标签名称"
else
echo "❌ 错误: 语义版本标签 $INPUT_TAG 不存在于仓库中"
echo "对于语义版本标签,必须先创建标签或启用 'force_build' 选项"
exit 1
fi
# 设置环境变量供后续步骤使用
echo "BUILD_TAG=$INPUT_TAG" >> $GITHUB_ENV
echo "IS_MANUAL_BUILD=true" >> $GITHUB_ENV
echo "TAG_TYPE=$TAG_TYPE" >> $GITHUB_ENV
echo "build_tag=$INPUT_TAG" >> $GITHUB_OUTPUT
echo "tag_type=$TAG_TYPE" >> $GITHUB_OUTPUT
else
# 标签推送触发时的处理
BUILD_TAG=${GITHUB_REF#refs/tags/}
echo "标签推送触发构建: $BUILD_TAG"
echo "BUILD_TAG=$BUILD_TAG" >> $GITHUB_ENV
echo "IS_MANUAL_BUILD=false" >> $GITHUB_ENV
echo "TAG_TYPE=semantic" >> $GITHUB_ENV
echo "build_tag=$BUILD_TAG" >> $GITHUB_OUTPUT
echo "tag_type=semantic" >> $GITHUB_OUTPUT
fi
echo "🏗️ 准备构建标签: $BUILD_TAG"
- name: 🔧 Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
platforms: linux/amd64,linux/arm64
- name: 🔑 Log in to Docker Hub
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: 🏷️ Extract metadata for Server image
id: meta-server
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_SERVER }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=raw,value=${{ env.BUILD_TAG }}
type=raw,value=latest,enable=${{ (github.event_name == 'push' && github.ref_name != '' && !contains(github.ref_name, '-')) || (env.IS_MANUAL_BUILD == 'true' && env.TAG_TYPE == 'semantic' && !contains(env.BUILD_TAG, '-')) }}
flavor: |
latest=false
- name: 🏷️ Extract metadata for Agent image
id: meta-agent
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_AGENT }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=raw,value=${{ env.BUILD_TAG }}
type=raw,value=latest,enable=${{ (github.event_name == 'push' && github.ref_name != '' && !contains(github.ref_name, '-')) || (env.IS_MANUAL_BUILD == 'true' && env.TAG_TYPE == 'semantic' && !contains(env.BUILD_TAG, '-')) }}
flavor: |
latest=false
- name: 🔍 Debug metadata output
run: |
echo "🏷️ Server image tags:"
echo "${{ steps.meta-server.outputs.tags }}"
echo ""
echo "🏷️ Agent image tags:"
echo "${{ steps.meta-agent.outputs.tags }}"
echo ""
echo "📋 Environment variables:"
echo " BUILD_TAG: ${{ env.BUILD_TAG }}"
echo " IS_MANUAL_BUILD: ${{ env.IS_MANUAL_BUILD }}"
echo " TAG_TYPE: ${{ env.TAG_TYPE }}"
echo " Event name: ${{ github.event_name }}"
echo " Ref: ${{ github.ref }}"
- name: 🐳 Build and push Server image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta-server.outputs.tags }}
labels: ${{ steps.meta-server.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: 🤖 Build and push Agent image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile_Agent
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta-agent.outputs.tags }}
labels: ${{ steps.meta-agent.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: 📊 Image digest
run: |
echo "Server image digest: ${{ steps.build-server.outputs.digest }}"
echo "Agent image digest: ${{ steps.build-agent.outputs.digest }}"
- name: 📋 Build Summary
run: |
echo "🎉 Docker 镜像构建完成!"
echo ""
echo "📋 构建信息:"
echo " 触发方式: ${{ github.event_name }}"
echo " 构建标签: ${{ env.BUILD_TAG }}"
echo " 手动构建: ${{ env.IS_MANUAL_BUILD }}"
if [ "${{ env.IS_MANUAL_BUILD }}" = "true" ]; then
echo " 标签类型: ${{ env.TAG_TYPE }}"
fi
echo ""
echo "🏷️ Server 镜像标签:"
echo "${{ steps.meta-server.outputs.tags }}" | sed 's/^/ - /'
echo ""
echo "🤖 Agent 镜像标签:"
echo "${{ steps.meta-agent.outputs.tags }}" | sed 's/^/ - /'
echo ""
if [ "${{ env.IS_MANUAL_BUILD }}" = "true" ]; then
echo "⚠️ 注意: 这是手动触发的构建"
if [ "${{ env.TAG_TYPE }}" = "custom" ]; then
echo "🔧 自定义版本: 基于当前分支代码构建"
fi
if [ "${{ github.event.inputs.force_build }}" = "true" ]; then
echo "⚠️ 警告: 使用了强制构建选项"
fi
fi