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

335 lines
12 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
steps:
- name: 检出代码
shell: bash
run: |
echo "📥 检出代码到工作目录..."
echo "当前目录: $(pwd)"
echo "仓库: ${{ gitea.repository }}"
echo "分支: ${{ gitea.ref }}"
echo "提交: ${{ gitea.sha }}"
# 解析分支名
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" .
if [ $? -ne 0 ]; then
echo "❌ 代码检出失败"
exit 1
fi
# 校验分支
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [ "$CURRENT_BRANCH" != "$BRANCH_NAME" ]; then
echo "❌ 检出分支与预期不符: $CURRENT_BRANCH != $BRANCH_NAME"
exit 1
fi
# 校验提交
CURRENT_COMMIT=$(git rev-parse HEAD)
if [ -n "${{ gitea.sha }}" ] && [ "$CURRENT_COMMIT" != "${{ gitea.sha }}" ]; then
echo "❌ 检出提交与预期不符: $CURRENT_COMMIT != ${{ gitea.sha }}"
exit 1
fi
echo "✅ 代码检出成功,分支和提交校验通过"
ls -la
- name: 安装Node.js环境
shell: bash
run: |
echo "🔧 安装Node.js环境..."
if command -v node &> /dev/null; then
echo "✅ Node.js已安装: $(node --version)"
echo "✅ npm已安装: $(npm --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
echo "验证Node.js安装..."
node --version
npm --version
rm node.tar.xz
echo "✅ Node.js安装完成"
fi
- name: 检查Node.js环境
shell: bash
run: |
echo "🔍 检查Node.js环境..."
export PATH=$PATH:/usr/local/bin
node --version
npm --version
echo "Node.js路径: $(which node)"
echo "npm路径: $(which npm)"
- 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
# 检查挂载点
echo "🔍 检查挂载点状态..."
CACHE_DIR="/shared/pnpm-cache"
echo "检查目录: $CACHE_DIR"
# 强制创建目录(如果挂载存在但目录为空)
mkdir -p "$CACHE_DIR"
if [ -d "$CACHE_DIR" ]; then
echo " ✅ 目录存在"
ls -la "$CACHE_DIR" | head -5
if [ -w "$CACHE_DIR" ]; then
echo " ✅ 目录可写"
else
echo " ❌ 目录不可写,尝试修复权限"
chmod 777 "$CACHE_DIR" 2>/dev/null || echo " 无法修复权限"
if [ -w "$CACHE_DIR" ]; then
echo " ✅ 权限修复成功"
else
echo " ❌ 权限修复失败"
CACHE_DIR=""
fi
fi
else
echo " ❌ 目录不存在"
CACHE_DIR=""
fi
if [ -z "$CACHE_DIR" ]; then
echo "⚠️ 未找到外部缓存目录,使用临时目录"
CACHE_DIR="/tmp/pnpm-cache"
mkdir -p "$CACHE_DIR"
else
echo "✅ 使用外部缓存目录: $CACHE_DIR"
fi
# 强制设置缓存目录,覆盖 .npmrc 中的配置
pnpm config set store-dir "$CACHE_DIR" --global
pnpm config set cache-dir "$CACHE_DIR" --global
echo "配置的缓存目录: $CACHE_DIR"
echo "pnpm 实际缓存目录: $(pnpm store path)"
# 验证配置是否生效
echo "验证 pnpm 配置:"
echo "store-dir: $(pnpm config get store-dir)"
echo "cache-dir: $(pnpm config get cache-dir)"
# 测试挂载是否工作
echo "🧪 测试挂载功能..."
TEST_FILE="$CACHE_DIR/test-mount.txt"
echo "测试时间: $(date)" > "$TEST_FILE"
if [ -f "$TEST_FILE" ]; then
echo "✅ 挂载测试成功,文件写入正常"
rm "$TEST_FILE"
else
echo "❌ 挂载测试失败,无法写入文件"
fi
# 检查缓存状态
if [ -d "$CACHE_DIR/v10" ]; then
echo "✅ 找到外部缓存"
du -sh "$CACHE_DIR"
echo "缓存文件数量: $(find "$CACHE_DIR" -type f | wc -l)"
else
echo "📥 首次运行,无缓存"
fi
- name: 输出 pnpm 缓存目录内容
shell: bash
run: |
echo "📂 输出 pnpm 缓存目录内容..."
CACHE_DIR="/shared/pnpm-cache"
if [ -d "$CACHE_DIR" ]; then
echo "--- $CACHE_DIR 内容 ---"
ls -lAh "$CACHE_DIR"
if [ -d "$CACHE_DIR/v10" ]; then
echo "--- $CACHE_DIR/v10 内容 ---"
ls -lAh "$CACHE_DIR/v10"
else
echo "$CACHE_DIR/v10 不存在"
fi
else
echo "$CACHE_DIR 不存在"
fi
- name: 缓存依赖
shell: bash
run: |
echo "📦 检查并恢复依赖缓存..."
export PATH=$PATH:/usr/local/bin
# 记录开始时间
START_TIME=$(date +%s)
# 使用外部缓存时的优化
echo "📦 使用外部缓存优化..."
pnpm config set prefer-offline true
# 检查 lockfile 是否存在
if [ -f "pnpm-lock.yaml" ]; then
echo "✅ 找到 pnpm-lock.yaml使用离线模式安装..."
echo "开始时间: $(date)"
pnpm install --frozen-lockfile
else
echo "📥 未找到 lockfile重新安装依赖..."
echo "开始时间: $(date)"
pnpm install
fi
# 记录结束时间
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
# 保存缓存信息
echo "📊 安装统计:"
echo "总耗时: ${DURATION}秒"
echo "缓存目录: $(pnpm store path)"
echo "缓存大小: $(du -sh $(pnpm store path) 2>/dev/null || echo 'N/A')"
# 检查缓存是否写入到外部目录
echo "🔍 检查外部缓存写入..."
if [ -d "/shared/pnpm-cache/v10" ]; then
echo "✅ 外部缓存写入成功"
du -sh /shared/pnpm-cache
echo "缓存文件数量: $(find /shared/pnpm-cache -type f | wc -l)"
else
echo "❌ 外部缓存写入失败"
echo "检查 pnpm 实际使用的缓存目录:"
pnpm store path
echo "检查外部目录内容:"
ls -la /shared/pnpm-cache/
fi
echo "✅ 依赖安装完成"
- name: 验证依赖
shell: bash
run: |
echo "🔍 验证项目依赖..."
export PATH=$PATH:/usr/local/bin
pnpm list --depth=0
echo "✅ 依赖验证完成"
- 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 "🚀 准备部署..."
echo "运行器操作系统: ${{ runner.os }}"
echo "工作目录: ${{ gitea.workspace }}"
echo "任务状态: ${{ job.status }}"
mkdir -p deploy
cp -r dist/* deploy/
echo "📦 部署包已准备完成"
# - name: 复制构建产物到目标目录
# shell: bash
# run: |
# echo "📤 复制构建产物到 /opt/dockeropt/epic-ui ..."
# mkdir -p /opt/dockeropt/epic-ui
# cp -r dist/* /opt/dockeropt/epic-ui/
# echo "✅ 构建产物已复制到 /opt/dockeropt/epic-ui"
# ls -la /opt/dockeropt/epic-ui/
# - name: 重启 Docker 容器
# shell: bash
# run: |
# echo "♻️ 重启 epic-ui 容器..."
# if ! command -v docker &> /dev/null; then
# if command -v apt-get &> /dev/null; then
# apt-get update && apt-get install -y docker.io
# elif command -v apk &> /dev/null; then
# echo "http://mirrors.aliyun.com/alpine/v3.20/main" > /etc/apk/repositories
# echo "http://mirrors.aliyun.com/alpine/v3.20/community" >> /etc/apk/repositories
# apk update
# apk add --no-cache docker-cli
# elif command -v yum &> /dev/null; then
# yum install -y docker
# fi
# fi
# docker ps -a
# docker restart epic-ui
# echo "✅ epic-ui 容器已重启"