/ .github / workflows / docker-publish.yml
docker-publish.yml
  1  name: 🐳 Build and Push Docker Images
  2  
  3  on:
  4    push:
  5      tags:
  6        - v*
  7    workflow_dispatch:
  8      inputs:
  9        tag:
 10          description: '手动指定标签版本 (例如: v1.0.0, dev, test, staging)'
 11          required: true
 12          type: string
 13        force_build:
 14          description: '强制构建 (即使标签不存在)'
 15          required: false
 16          type: boolean
 17          default: false
 18  
 19  env:
 20    REGISTRY: docker.io
 21    IMAGE_NAME_SERVER: zhuquelab/aig-server
 22    IMAGE_NAME_AGENT: zhuquelab/aig-agent
 23  
 24  jobs:
 25    build-and-push:
 26      runs-on: ubuntu-latest
 27      permissions:
 28        contents: read
 29        packages: write
 30  
 31      steps:
 32        - name: 🛒 Checkout repository
 33          uses: actions/checkout@v4
 34          with:
 35            fetch-depth: 0
 36  
 37        - name: 🏷️ Validate and setup tag
 38          id: tag-setup
 39          run: |
 40            if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
 41              # 手动触发时的标签处理
 42              INPUT_TAG="${{ github.event.inputs.tag }}"
 43              FORCE_BUILD="${{ github.event.inputs.force_build }}"
 44              
 45              echo "手动触发构建,指定标签: $INPUT_TAG"
 46              
 47              # 简化的标签格式验证
 48              # 支持更灵活的标签格式
 49              if [[ "$INPUT_TAG" =~ ^v[0-9]+(\.[0-9]+)*(-[a-zA-Z0-9]+)*(\+[a-zA-Z0-9]+)*$ ]]; then
 50                echo "✅ 检测到语义版本标签: $INPUT_TAG"
 51                TAG_TYPE="semantic"
 52              elif [[ "$INPUT_TAG" =~ ^[a-zA-Z0-9][a-zA-Z0-9._-]*$ ]]; then
 53                echo "✅ 检测到自定义标签: $INPUT_TAG"
 54                TAG_TYPE="custom"
 55              else
 56                echo "⚠️  警告: 标签格式可能不规范,但将继续构建: $INPUT_TAG"
 57                TAG_TYPE="custom"
 58              fi
 59              
 60              # 检查标签是否存在并处理
 61              if git tag -l | grep -q "^$INPUT_TAG$"; then
 62                echo "✅ 标签 $INPUT_TAG 存在于仓库中"
 63                # 切换到指定标签
 64                git checkout $INPUT_TAG
 65              elif [ "$TAG_TYPE" = "custom" ]; then
 66                echo "ℹ️  自定义标签 $INPUT_TAG 不存在于仓库中"
 67                echo "将基于当前分支构建自定义版本镜像"
 68                # 自定义标签默认允许基于当前代码构建
 69              elif [ "$FORCE_BUILD" = "true" ]; then
 70                echo "⚠️  警告: 语义版本标签 $INPUT_TAG 不存在,但启用了强制构建"
 71                echo "将基于当前分支构建,但使用指定的标签名称"
 72              else
 73                echo "❌ 错误: 语义版本标签 $INPUT_TAG 不存在于仓库中"
 74                echo "对于语义版本标签,必须先创建标签或启用 'force_build' 选项"
 75                exit 1
 76              fi
 77              
 78              # 设置环境变量供后续步骤使用
 79              echo "BUILD_TAG=$INPUT_TAG" >> $GITHUB_ENV
 80              echo "IS_MANUAL_BUILD=true" >> $GITHUB_ENV
 81              echo "TAG_TYPE=$TAG_TYPE" >> $GITHUB_ENV
 82              echo "build_tag=$INPUT_TAG" >> $GITHUB_OUTPUT
 83              echo "tag_type=$TAG_TYPE" >> $GITHUB_OUTPUT
 84              
 85            else
 86              # 标签推送触发时的处理
 87              BUILD_TAG=${GITHUB_REF#refs/tags/}
 88              echo "标签推送触发构建: $BUILD_TAG"
 89              echo "BUILD_TAG=$BUILD_TAG" >> $GITHUB_ENV
 90              echo "IS_MANUAL_BUILD=false" >> $GITHUB_ENV
 91              echo "TAG_TYPE=semantic" >> $GITHUB_ENV
 92              echo "build_tag=$BUILD_TAG" >> $GITHUB_OUTPUT
 93              echo "tag_type=semantic" >> $GITHUB_OUTPUT
 94            fi
 95            
 96            echo "🏗️  准备构建标签: $BUILD_TAG"
 97  
 98        - name: 🔧 Set up Docker Buildx
 99          uses: docker/setup-buildx-action@v3
100          with:
101            platforms: linux/amd64,linux/arm64
102  
103        - name: 🔑 Log in to Docker Hub
104          uses: docker/login-action@v3
105          with:
106            registry: ${{ env.REGISTRY }}
107            username: ${{ secrets.DOCKERHUB_USERNAME }}
108            password: ${{ secrets.DOCKERHUB_TOKEN }}
109  
110        - name: 🏷️ Extract metadata for Server image
111          id: meta-server
112          uses: docker/metadata-action@v5
113          with:
114            images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_SERVER }}
115            tags: |
116              type=ref,event=branch
117              type=semver,pattern={{version}}
118              type=raw,value=${{ env.BUILD_TAG }}
119              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, '-')) }}
120            flavor: |
121              latest=false
122  
123        - name: 🏷️ Extract metadata for Agent image
124          id: meta-agent
125          uses: docker/metadata-action@v5
126          with:
127            images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_AGENT }}
128            tags: |
129              type=ref,event=branch
130              type=semver,pattern={{version}}
131              type=raw,value=${{ env.BUILD_TAG }}
132              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, '-')) }}
133            flavor: |
134              latest=false
135  
136        - name: 🔍 Debug metadata output
137          run: |
138            echo "🏷️ Server image tags:"
139            echo "${{ steps.meta-server.outputs.tags }}"
140            echo ""
141            echo "🏷️ Agent image tags:"
142            echo "${{ steps.meta-agent.outputs.tags }}"
143            echo ""
144            echo "📋 Environment variables:"
145            echo "  BUILD_TAG: ${{ env.BUILD_TAG }}"
146            echo "  IS_MANUAL_BUILD: ${{ env.IS_MANUAL_BUILD }}"
147            echo "  TAG_TYPE: ${{ env.TAG_TYPE }}"
148            echo "  Event name: ${{ github.event_name }}"
149            echo "  Ref: ${{ github.ref }}"
150  
151        - name: 🐳 Build and push Server image
152          uses: docker/build-push-action@v5
153          with:
154            context: .
155            file: ./Dockerfile
156            platforms: linux/amd64,linux/arm64
157            push: true
158            tags: ${{ steps.meta-server.outputs.tags }}
159            labels: ${{ steps.meta-server.outputs.labels }}
160            cache-from: type=gha
161            cache-to: type=gha,mode=max
162  
163        - name: 🤖 Build and push Agent image
164          uses: docker/build-push-action@v5
165          with:
166            context: .
167            file: ./Dockerfile_Agent
168            platforms: linux/amd64,linux/arm64
169            push: true
170            tags: ${{ steps.meta-agent.outputs.tags }}
171            labels: ${{ steps.meta-agent.outputs.labels }}
172            cache-from: type=gha
173            cache-to: type=gha,mode=max
174  
175        - name: 📊 Image digest
176          run: |
177            echo "Server image digest: ${{ steps.build-server.outputs.digest }}"
178            echo "Agent image digest: ${{ steps.build-agent.outputs.digest }}"
179  
180        - name: 📋 Build Summary
181          run: |
182            echo "🎉 Docker 镜像构建完成!"
183            echo ""
184            echo "📋 构建信息:"
185            echo "  触发方式: ${{ github.event_name }}"
186            echo "  构建标签: ${{ env.BUILD_TAG }}"
187            echo "  手动构建: ${{ env.IS_MANUAL_BUILD }}"
188            if [ "${{ env.IS_MANUAL_BUILD }}" = "true" ]; then
189              echo "  标签类型: ${{ env.TAG_TYPE }}"
190            fi
191            echo ""
192            echo "🏷️ Server 镜像标签:"
193            echo "${{ steps.meta-server.outputs.tags }}" | sed 's/^/  - /'
194            echo ""
195            echo "🤖 Agent 镜像标签:"
196            echo "${{ steps.meta-agent.outputs.tags }}" | sed 's/^/  - /'
197            echo ""
198            if [ "${{ env.IS_MANUAL_BUILD }}" = "true" ]; then
199              echo "⚠️  注意: 这是手动触发的构建"
200              if [ "${{ env.TAG_TYPE }}" = "custom" ]; then
201                echo "🔧 自定义版本: 基于当前分支代码构建"
202              fi
203              if [ "${{ github.event.inputs.force_build }}" = "true" ]; then
204                echo "⚠️  警告: 使用了强制构建选项"
205              fi
206            fi