Files
ogame-vue-ts/.github/workflows/ogame-vue-ts.yml
coolxitech 9634dcb023 build(ci): 优化 Docker 构建流程并添加多平台支持
- 在 Dockerfile 中添加构建参数和标签信息用于缓存破坏
- 使用 --chown 确保正确的文件权限并验证构建产物
- 添加构建产物时间戳检查以确保最新性
- 获取并使用版本号进行镜像标签管理
- 添加清理冲突镜像标签的步骤
- 配置多平台构建支持(linux/amd64,linux/arm64)
- 添加版本标签和构建参数传递
- 配置构建缓存和镜像推送功能
2026-01-08 17:55:40 +08:00

180 lines
6.5 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: 构建并发布 Docker 镜像
on:
push:
branches: [main]
tags: ['v*.*.*'] # 打 tag 时也触发
workflow_dispatch:
permissions:
contents: read
packages: write
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v6
with:
fetch-depth: 0
# 设置 Node.js 环境
- name: 设置 Node.js
uses: actions/setup-node@v6
with:
node-version: '20'
# 设置 pnpm
- name: 设置 pnpm
uses: pnpm/action-setup@v4
with:
version: latest
# 缓存 pnpm 依赖
- name: 缓存 pnpm 依赖
uses: actions/cache@v5
with:
path: |
~/.pnpm-store
node_modules
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
# 安装依赖
- name: 安装依赖
run: pnpm install --frozen-lockfile
# 构建项目
- name: 构建项目
run: pnpm run build
# 验证构建产物
- name: 验证构建产物
run: |
if [ ! -d "docs" ]; then
echo "❌ 构建失败docs 目录不存在"
exit 1
fi
if [ ! -f "docs/index.html" ]; then
echo "❌ 构建失败docs/index.html 不存在"
exit 1
fi
# 检查构建产物的时间戳,确保是最新的
BUILD_TIME=$(stat -c %Y docs/index.html 2>/dev/null || stat -f %m docs/index.html 2>/dev/null || echo "0")
CURRENT_TIME=$(date +%s)
TIME_DIFF=$((CURRENT_TIME - BUILD_TIME))
echo "📊 构建产物信息:"
echo " 构建时间: $(date -d @$BUILD_TIME 2>/dev/null || date -r $BUILD_TIME 2>/dev/null || echo '未知')"
echo " 当前时间: $(date)"
echo " 时间差: ${TIME_DIFF}秒"
if [ $TIME_DIFF -gt 300 ]; then
echo "⚠️ 警告: 构建产物可能不是最新的超过5分钟"
fi
echo "✅ 构建产物验证通过"
ls -la docs/
# 获取当前日期
- name: 获取当前日期
id: date
run: echo "date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
# 获取版本号
- name: 获取版本号
id: version
run: |
VERSION=$(node -p "require('./package.json').version")
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "📦 当前版本: $VERSION"
# 准备 CI 构建环境
- name: 准备 CI 构建环境
run: |
# 使用 CI 专用的 dockerignore
cp .dockerignore.ci .dockerignore
echo "✅ 已切换到 CI 构建模式"
echo "📁 当前构建上下文文件:"
ls -la | grep -E "(docs|nginx.conf|Dockerfile.ci|\.dockerignore)$"
# 清理可能冲突的镜像标签
- name: 清理可能冲突的镜像标签
continue-on-error: true
run: |
VERSION="${{ steps.version.outputs.version }}"
echo "🧹 尝试清理可能冲突的镜像标签..."
# 尝试删除 GHCR 中的现有标签(如果存在)
echo "清理 GHCR 标签..."
docker buildx imagetools inspect ghcr.io/${{ github.repository_owner }}/ogame-vue-ts:$VERSION 2>/dev/null && \
echo "发现现有版本标签,将被覆盖" || echo "版本标签不存在,可以安全推送"
# 如果配置了 Docker Hub也尝试检查
if [ -n "${{ vars.DOCKERHUB_USERNAME }}" ]; then
echo "检查 Docker Hub 标签..."
docker buildx imagetools inspect ${{ vars.DOCKERHUB_USERNAME }}/ogame-vue-ts:$VERSION 2>/dev/null && \
echo "发现现有 Docker Hub 版本标签,将被覆盖" || echo "Docker Hub 版本标签不存在,可以安全推送"
fi
echo "✅ 标签冲突检查完成,构建将覆盖任何现有标签"
# QEMU 用于支持多架构构建(必须)
- name: 设置 QEMU
uses: docker/setup-qemu-action@v3
# Buildx 是目前官方唯一推荐的多架构构建方式
- name: 设置 Docker Buildx
uses: docker/setup-buildx-action@v3
# 登录 GHCR始终执行
- name: 登录 GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# 登录 Docker Hub只在用户名存在时执行
- name: 登录 Docker Hub
if: vars.DOCKERHUB_USERNAME != '' # 只检查 vars忽略 secrets
uses: docker/login-action@v3
with:
username: ${{ vars.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# 构建并推送多架构镜像(使用构建产物)
- name: 构建并推送多架构镜像
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile.ci
platforms: linux/amd64,linux/arm64
push: true
no-cache: false
pull: true
tags: |
ghcr.io/${{ github.repository_owner }}/ogame-vue-ts:latest
ghcr.io/${{ github.repository_owner }}/ogame-vue-ts:${{ steps.version.outputs.version }}
ghcr.io/${{ github.repository_owner }}/ogame-vue-ts:${{ github.sha }}
${{ vars.DOCKERHUB_USERNAME && format('{0}/ogame-vue-ts:latest', vars.DOCKERHUB_USERNAME) || '' }}
${{ vars.DOCKERHUB_USERNAME && format('{0}/ogame-vue-ts:{1}', vars.DOCKERHUB_USERNAME, steps.version.outputs.version) || '' }}
${{ vars.DOCKERHUB_USERNAME && format('{0}/ogame-vue-ts:{1}', vars.DOCKERHUB_USERNAME, github.sha) || '' }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
BUILDKIT_INLINE_CACHE=1
BUILD_DATE=${{ steps.date.outputs.date }}
VERSION=${{ steps.version.outputs.version }}
COMMIT_SHA=${{ github.sha }}
labels: |
org.opencontainers.image.title=OGame Vue Ts
org.opencontainers.image.description=OGame Vue TypeScript Implementation
org.opencontainers.image.version=${{ steps.version.outputs.version }}
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.created=${{ steps.date.outputs.date }}