143 lines
4.0 KiB
YAML
143 lines
4.0 KiB
YAML
name: 'Reusable Docker Image Build'
|
||
description: '通用的 Docker 镜像构建 / 验证 / 清理逻辑,用于在各仓库中复用'
|
||
|
||
inputs:
|
||
dockerfile:
|
||
description: 'Dockerfile 路径(相对于仓库根目录)'
|
||
required: true
|
||
context:
|
||
description: '构建上下文路径(相对于仓库根目录)'
|
||
required: false
|
||
default: '.'
|
||
image_name:
|
||
description: 'Docker 镜像名称(不含标签)'
|
||
required: true
|
||
image_tag:
|
||
description: 'Docker 镜像标签/版本'
|
||
required: true
|
||
enable_cache:
|
||
description: '是否启用 Docker 构建缓存'
|
||
required: false
|
||
default: 'true'
|
||
build_args:
|
||
description: 'Docker 构建参数(每行一个,格式: KEY=VALUE)'
|
||
required: false
|
||
default: ''
|
||
|
||
runs:
|
||
using: 'composite'
|
||
steps:
|
||
- name: Prepare build arguments
|
||
id: prepare
|
||
shell: bash
|
||
run: |
|
||
echo "====== 准备构建参数 ======"
|
||
|
||
DOCKERFILE="${{ inputs.dockerfile }}"
|
||
CONTEXT="${{ inputs.context }}"
|
||
IMAGE_NAME="${{ inputs.image_name }}"
|
||
IMAGE_TAG="${{ inputs.image_tag }}"
|
||
FULL_IMAGE="${IMAGE_NAME}:${IMAGE_TAG}"
|
||
|
||
echo "Dockerfile: $DOCKERFILE"
|
||
echo "Context: $CONTEXT"
|
||
echo "Image: $FULL_IMAGE"
|
||
|
||
# 验证 Dockerfile 是否存在
|
||
if [ ! -f "$DOCKERFILE" ]; then
|
||
echo "✗ Dockerfile 不存在: $DOCKERFILE"
|
||
exit 1
|
||
fi
|
||
|
||
# 验证构建上下文目录是否存在
|
||
if [ ! -d "$CONTEXT" ]; then
|
||
echo "✗ 构建上下文目录不存在: $CONTEXT"
|
||
exit 1
|
||
fi
|
||
|
||
echo "✓ 构建参数验证通过"
|
||
echo ""
|
||
|
||
# 设置输出变量
|
||
echo "full_image=$FULL_IMAGE" >> "$GITHUB_OUTPUT"
|
||
|
||
# 处理构建参数
|
||
BUILD_ARGS=""
|
||
if [ -n "${{ inputs.build_args }}" ]; then
|
||
echo "====== 构建参数 ======"
|
||
while IFS= read -r line; do
|
||
if [ -n "$line" ]; then
|
||
echo " $line"
|
||
BUILD_ARGS="$BUILD_ARGS --build-arg $line"
|
||
fi
|
||
done <<< "${{ inputs.build_args }}"
|
||
echo ""
|
||
fi
|
||
|
||
echo "build_args=$BUILD_ARGS" >> "$GITHUB_OUTPUT"
|
||
|
||
- name: Build Docker image
|
||
shell: bash
|
||
run: |
|
||
echo "====== 开始构建 Docker 镜像 ======"
|
||
echo "构建时间: $(date '+%Y-%m-%d %H:%M:%S')"
|
||
echo "分支: ${{ github.ref_name }}"
|
||
echo ""
|
||
|
||
echo "====== 构建配置 ======"
|
||
echo "镜像: ${{ steps.prepare.outputs.full_image }}"
|
||
echo "Dockerfile: ${{ inputs.dockerfile }}"
|
||
echo "Context: ${{ inputs.context }}"
|
||
echo ""
|
||
|
||
# 构建命令
|
||
BUILD_CMD="docker build \
|
||
-t ${{ steps.prepare.outputs.full_image }} \
|
||
-f ${{ inputs.dockerfile }} \
|
||
${{ steps.prepare.outputs.build_args }} \
|
||
${{ inputs.context }}"
|
||
|
||
echo "执行命令:"
|
||
echo "$BUILD_CMD"
|
||
echo ""
|
||
|
||
# 执行构建
|
||
eval $BUILD_CMD
|
||
|
||
echo ""
|
||
echo "====== 镜像构建完成 ======"
|
||
|
||
- name: Verify image
|
||
shell: bash
|
||
run: |
|
||
echo "====== 验证构建的镜像 ======"
|
||
|
||
IMAGE="${{ steps.prepare.outputs.full_image }}"
|
||
|
||
if docker image inspect "${IMAGE}" >/dev/null 2>&1; then
|
||
SIZE=$(docker image inspect "${IMAGE}" --format='{{.Size}}' | awk '{printf "%.2f", $1/1024/1024}')
|
||
CREATED=$(docker image inspect "${IMAGE}" --format='{{.Created}}')
|
||
ID=$(docker image inspect "${IMAGE}" --format='{{.Id}}' | cut -d':' -f2 | cut -c1-12)
|
||
|
||
echo "✓ ${IMAGE}"
|
||
echo " 镜像 ID: ${ID}"
|
||
echo " 大小: ${SIZE} MB"
|
||
echo " 创建时间: ${CREATED}"
|
||
else
|
||
echo "✗ ${IMAGE} 验证失败"
|
||
exit 1
|
||
fi
|
||
|
||
echo ""
|
||
echo "✓ 镜像验证成功"
|
||
|
||
- name: Cleanup
|
||
if: always()
|
||
shell: bash
|
||
run: |
|
||
echo "====== 清理悬空镜像 ======"
|
||
docker image prune -f
|
||
echo "✓ 清理完成"
|
||
|
||
|