Files
epic-ui/.gitea/workflows/ci.yaml
hu xiaotong 23bef2484e ci: 添加 Epic UI 构建和部署工作流
- 新增 CI/CD 工作流文件,实现前端项目的自动构建和部署
- 支持 main、master 和 develop 分支的自动构建- 包含代码检出、环境安装、依赖管理、项目构建等步骤
- 实现构建产物的自动部署和 Docker 容器重启
2025-07-08 13:20:47 +08:00

297 lines
10 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: Epic UI Build & Deploy
run-name: ${{ gitea.actor }} 正在构建 Epic UI 前端项目 🚀
on:
push:
branches: [ main, master, develop ]
pull_request:
branches: [ main, master ]
jobs:
build:
runs-on: gitea_labels
container:
image: gitea-ci-bash:latest
env:
# 指定容器将工具缓存路径存放到 /opt/hostedtoolcache该目录是Gitea Runner的标准工具缓存目录
RUNNER_TOOL_CACHE: /opt/hostedtoolcache
volumes:
# 直接挂载到指定的宿主机路径
- /opt/gitea-runner-cache:/opt/hostedtoolcache
# 挂载生产环境目录
- /opt/1panel/apps/openresty/openresty/www/sites/epic7/index:/opt/prod
steps:
- name: 检出代码
shell: bash
run: |
echo "📥 检出代码到工作目录..."
# 解析分支名
BRANCH_NAME=$(echo "${{ gitea.ref }}" | sed 's#refs/heads/##')
# 拉取代码使用token鉴权
git clone --depth=1 -b "$BRANCH_NAME" "http://1c18ee1ab9a9cb291506d0c5c016a33be7d59e8c:x-oauth-basic@gitea.htoop.cn/${{ gitea.repository }}.git" .
echo "✅ 代码检出成功"
- name: 安装Node.js环境
shell: bash
run: |
echo "🔧 安装Node.js环境..."
if command -v node &> /dev/null; then
echo "✅ Node.js已安装: $(node --version)"
else
echo "📥 下载并安装Node.js..."
NODE_VERSION="18.19.0"
NODE_ARCH="linux-x64"
MIRRORS=(
"https://mirrors.aliyun.com/nodejs-release/v${NODE_VERSION}/node-v${NODE_VERSION}-${NODE_ARCH}.tar.xz"
"https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-${NODE_ARCH}.tar.xz"
)
DOWNLOAD_SUCCESS=false
for mirror in "${MIRRORS[@]}"; do
echo "尝试从镜像下载: $mirror"
if wget -q --timeout=30 --tries=3 "$mirror" -O node.tar.xz; then
echo "✅ 下载成功: $mirror"
DOWNLOAD_SUCCESS=true
break
else
echo "❌ 下载失败: $mirror"
continue
fi
done
if [ "$DOWNLOAD_SUCCESS" = false ]; then
echo "❌ 所有镜像源下载失败"
exit 1
fi
echo "解压Node.js到/usr/local..."
tar -C /usr/local -xJf node.tar.xz --strip-components=1
export PATH=$PATH:/usr/local/bin
rm node.tar.xz
echo "✅ Node.js安装完成"
fi
- name: 安装pnpm
shell: bash
run: |
echo "📦 安装pnpm包管理器..."
export PATH=$PATH:/usr/local/bin
if command -v pnpm &> /dev/null; then
echo "✅ pnpm已安装: $(pnpm --version)"
else
echo "📥 安装pnpm..."
npm install -g pnpm
echo "✅ pnpm安装完成: $(pnpm --version)"
fi
- name: 配置pnpm缓存
shell: bash
run: |
echo "📦 配置pnpm缓存..."
export PATH=$PATH:/usr/local/bin
# 配置pnpm缓存目录
PNPM_STORE_DIR="/opt/hostedtoolcache/pnpm-store"
mkdir -p "$PNPM_STORE_DIR"
# 设置pnpm使用缓存目录
pnpm config set store-dir "$PNPM_STORE_DIR"
pnpm config set cache-dir "/opt/hostedtoolcache/pnpm-cache"
echo "✅ pnpm缓存配置完成"
- name: 恢复依赖缓存
shell: bash
run: |
echo "📦 检查并恢复依赖缓存..."
export PATH=$PATH:/usr/local/bin
# 生成缓存键
CACHE_KEY=$(md5sum pnpm-lock.yaml | cut -d' ' -f1)
echo "缓存键: $CACHE_KEY"
# 使用 /opt/hostedtoolcache 目录
CACHE_FILE="/opt/hostedtoolcache/node_modules_${CACHE_KEY}.tar.gz"
echo "📁 检查缓存文件: $CACHE_FILE"
if [ -f "$CACHE_FILE" ]; then
echo "✅ 找到缓存文件: $CACHE_FILE"
echo "📦 缓存文件大小: $(du -sh "$CACHE_FILE" | cut -f1)"
echo "正在恢复缓存..."
if tar -xzf "$CACHE_FILE"; then
echo "✅ 缓存恢复成功"
echo "📦 恢复的 node_modules 大小:"
du -sh node_modules 2>/dev/null || echo "node_modules 目录不存在"
else
echo "❌ 缓存恢复失败"
echo "📥 将重新安装依赖"
fi
else
echo "📥 未找到缓存文件,将重新安装依赖"
fi
- name: 安装项目依赖
shell: bash
run: |
echo "📦 安装项目依赖..."
export PATH=$PATH:/usr/local/bin
# 检查是否已有node_modules
if [ -d "node_modules" ] && [ -f "node_modules/.pnpm-debug.log" ]; then
echo "✅ 检测到已存在的依赖,跳过安装"
else
echo "📥 安装项目依赖..."
pnpm install --frozen-lockfile --prefer-offline
echo "✅ 依赖安装完成"
fi
- name: 保存依赖缓存
shell: bash
run: |
echo "💾 保存依赖缓存..."
export PATH=$PATH:/usr/local/bin
# 生成缓存键
CACHE_KEY=$(md5sum pnpm-lock.yaml | cut -d' ' -f1)
echo "缓存键: $CACHE_KEY"
# 检查node_modules是否存在
if [ ! -d "node_modules" ]; then
echo "❌ node_modules 目录不存在,跳过缓存保存"
exit 0
fi
# 检查缓存文件是否已存在且是最新的
CACHE_FILE="/opt/hostedtoolcache/node_modules_${CACHE_KEY}.tar.gz"
if [ -f "$CACHE_FILE" ]; then
echo "✅ 缓存文件已存在且是最新的,跳过创建: $CACHE_FILE"
echo "📦 现有缓存文件大小: $(du -sh "$CACHE_FILE" | cut -f1)"
exit 0
fi
# 缓存文件不存在,需要创建
echo "📦 正在创建缓存文件: $CACHE_FILE"
if tar -czf "$CACHE_FILE" node_modules; then
echo "✅ 缓存已保存到: $CACHE_FILE"
echo "📦 缓存文件大小: $(du -sh "$CACHE_FILE" | cut -f1)"
else
echo "❌ 缓存保存失败"
exit 1
fi
- name: 构建项目
shell: bash
run: |
echo "🔨 构建 Epic UI 前端项目..."
export PATH=$PATH:/usr/local/bin
# 执行构建
pnpm build
echo "✅ 构建完成"
- name: 检查构建产物
shell: bash
run: |
echo "📦 构建产物信息:"
if [ -d "dist" ]; then
echo "✅ 找到dist目录"
ls -la dist/
echo "dist目录大小: $(du -sh dist | cut -f1)"
else
echo "❌ 未找到dist目录"
exit 1
fi
- name: 显示项目信息
shell: bash
run: |
echo "📋 项目信息:"
export PATH=$PATH:/usr/local/bin
echo "Node.js 版本: $(node --version)"
echo "npm 版本: $(npm --version)"
echo "pnpm 版本: $(pnpm --version)"
echo "构建时间: $(date)"
echo "分支: ${{ gitea.ref }}"
echo "提交: ${{ gitea.sha }}"
- name: 部署到生产环境
shell: bash
run: |
echo "🚀 部署到生产环境..."
# 生产环境目录容器内路径直接映射到nginx静态文件目录
PROD_DIR="/opt/prod"
# 检查构建产物
if [ ! -d "dist" ]; then
echo "❌ 构建产物不存在"
exit 1
fi
echo "📦 构建产物内容:"
ls -la dist/
# 检查生产目录挂载
echo "📁 检查生产目录挂载状态..."
if [ -d "$PROD_DIR" ]; then
echo "✅ 生产目录已存在: $PROD_DIR"
echo "📁 当前生产目录内容:"
ls -la "$PROD_DIR" 2>/dev/null || echo "目录为空或无法访问"
else
echo "📁 生产目录不存在,将创建: $PROD_DIR"
fi
# 备份当前生产环境
if [ -d "$PROD_DIR" ] && [ "$(ls -A "$PROD_DIR" 2>/dev/null)" ]; then
BACKUP_DIR="/opt/prod_backup_$(date +%Y%m%d_%H%M%S)"
echo "📦 备份当前生产环境到: $BACKUP_DIR"
cp -r "$PROD_DIR" "$BACKUP_DIR"
fi
# 确保生产目录存在并清空
echo "📤 部署构建产物到nginx静态文件目录..."
mkdir -p "$PROD_DIR"
rm -rf "$PROD_DIR"/*
# 复制构建产物到生产环境
echo "📦 复制构建产物..."
if cp -r dist/* "$PROD_DIR/"; then
echo "✅ 构建产物复制成功"
else
echo "❌ 构建产物复制失败"
echo "📁 检查目标目录权限和空间..."
df -h "$PROD_DIR" 2>/dev/null || echo "无法检查磁盘空间"
ls -ld "$PROD_DIR" 2>/dev/null || echo "无法检查目录权限"
exit 1
fi
# 设置权限
chmod -R 755 "$PROD_DIR"
# 强制同步文件系统
echo "🔄 同步文件系统..."
sync
echo "✅ 部署完成"
echo "📁 生产环境目录: $PROD_DIR (对应宿主机: /opt/1panel/apps/openresty/openresty/www/sites/epic7/index)"
echo "📦 部署的文件:"
ls -la "$PROD_DIR"
# 验证部署结果
echo "🔍 验证部署结果..."
echo "📋 文件数量: $(find "$PROD_DIR" -type f | wc -l)"
echo "📋 目录数量: $(find "$PROD_DIR" -type d | wc -l)"
echo "📋 总大小: $(du -sh "$PROD_DIR" | cut -f1)"
# 检查关键文件
if [ -f "$PROD_DIR/index.html" ]; then
echo "✅ index.html 存在"
echo "📋 index.html 大小: $(ls -lh "$PROD_DIR/index.html" | awk '{print $5}')"
else
echo "❌ index.html 不存在"
fi