diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index 306bac4..2026aa4 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -11,9 +11,9 @@ jobs: runs-on: gitea_labels container: image: gitea-ci-bash:latest - env: - # 方法一,指定容器将工具缓存路径存放到 /toolcache ,该目录actRunner会默认持久化它 - RUNNER_TOOL_CACHE: /toolcache + env: + # 指定容器将工具缓存路径存放到 /opt/hostedtoolcache,该目录是Gitea Runner的标准工具缓存目录 + RUNNER_TOOL_CACHE: /opt/hostedtoolcache steps: - name: 检出代码 shell: bash @@ -119,8 +119,8 @@ jobs: shell: bash run: | echo "🔍 检查缓存目录权限和状态..." - echo "=== /toolcache 目录检查 ===" - ls -la /toolcache/ 2>/dev/null || echo "/toolcache 目录不存在或无法访问" + echo "=== /opt/hostedtoolcache 目录检查 ===" + ls -la /opt/hostedtoolcache/ 2>/dev/null || echo "/opt/hostedtoolcache 目录不存在或无法访问" echo "=== /shared/cache 目录检查 ===" ls -la /shared/cache/ 2>/dev/null || echo "/shared/cache 目录不存在或无法访问" echo "=== /tmp 目录检查 ===" @@ -129,54 +129,54 @@ jobs: pwd ls -la - - name: 配置toolcache缓存目录 + - name: 配置hostedtoolcache缓存目录 shell: bash run: | - echo "🔧 配置 /toolcache 缓存目录..." + echo "🔧 配置 /opt/hostedtoolcache 缓存目录..." - # 检查 /toolcache 目录 - if [ ! -d "/toolcache" ]; then - echo "📁 /toolcache 目录不存在,尝试创建..." - if mkdir -p "/toolcache" 2>/dev/null; then - echo "✅ /toolcache 目录创建成功" + # 检查 /opt/hostedtoolcache 目录 + if [ ! -d "/opt/hostedtoolcache" ]; then + echo "📁 /opt/hostedtoolcache 目录不存在,尝试创建..." + if mkdir -p "/opt/hostedtoolcache" 2>/dev/null; then + echo "✅ /opt/hostedtoolcache 目录创建成功" else - echo "❌ /toolcache 目录创建失败" + echo "❌ /opt/hostedtoolcache 目录创建失败" exit 1 fi fi # 检查目录权限 - if [ -w "/toolcache" ]; then - echo "✅ /toolcache 目录可写" + if [ -w "/opt/hostedtoolcache" ]; then + echo "✅ /opt/hostedtoolcache 目录可写" # 设置权限 - chmod 755 "/toolcache" 2>/dev/null || echo "⚠️ 无法设置权限" + chmod 755 "/opt/hostedtoolcache" 2>/dev/null || echo "⚠️ 无法设置权限" # 创建测试文件 - TEST_FILE="/toolcache/test_write_$(date +%s)" + TEST_FILE="/opt/hostedtoolcache/test_write_$(date +%s)" if touch "$TEST_FILE" 2>/dev/null; then - echo "✅ /toolcache 写入测试成功" + echo "✅ /opt/hostedtoolcache 写入测试成功" rm -f "$TEST_FILE" - echo "CACHE_DIR=/toolcache" >> $GITHUB_ENV + echo "CACHE_DIR=/opt/hostedtoolcache" >> $GITHUB_ENV else - echo "❌ /toolcache 写入测试失败" + echo "❌ /opt/hostedtoolcache 写入测试失败" exit 1 fi else - echo "❌ /toolcache 目录不可写" + echo "❌ /opt/hostedtoolcache 目录不可写" echo "🔧 尝试修改目录权限..." - chmod 755 "/toolcache" 2>/dev/null || echo "⚠️ 无法修改权限" - if [ -w "/toolcache" ]; then + chmod 755 "/opt/hostedtoolcache" 2>/dev/null || echo "⚠️ 无法修改权限" + if [ -w "/opt/hostedtoolcache" ]; then echo "✅ 权限修改成功" - echo "CACHE_DIR=/toolcache" >> $GITHUB_ENV + echo "CACHE_DIR=/opt/hostedtoolcache" >> $GITHUB_ENV else - echo "❌ 无法获得 /toolcache 写入权限" + echo "❌ 无法获得 /opt/hostedtoolcache 写入权限" exit 1 fi fi - echo "📊 缓存目录配置: /toolcache" + echo "📊 缓存目录配置: /opt/hostedtoolcache" echo "📁 目录内容:" - ls -la /toolcache/ 2>/dev/null || echo "目录为空或无法访问" + ls -la /opt/hostedtoolcache/ 2>/dev/null || echo "目录为空或无法访问" - name: 恢复依赖缓存 shell: bash @@ -187,8 +187,8 @@ jobs: CACHE_KEY=$(md5sum pnpm-lock.yaml | cut -d' ' -f1) echo "缓存键: $CACHE_KEY" - # 只使用 /toolcache 目录 - CACHE_FILE="/toolcache/node_modules_${CACHE_KEY}.tar.gz" + # 使用 /opt/hostedtoolcache 目录 + CACHE_FILE="/opt/hostedtoolcache/node_modules_${CACHE_KEY}.tar.gz" echo "📁 检查缓存文件: $CACHE_FILE" if [ -f "$CACHE_FILE" ]; then @@ -265,8 +265,8 @@ jobs: exit 0 fi - # 只保存到 /toolcache 目录 - CACHE_FILE="/toolcache/node_modules_${CACHE_KEY}.tar.gz" + # 保存到 /opt/hostedtoolcache 目录 + CACHE_FILE="/opt/hostedtoolcache/node_modules_${CACHE_KEY}.tar.gz" echo "📦 正在创建缓存文件: $CACHE_FILE" if tar -czf "$CACHE_FILE" node_modules; then @@ -274,13 +274,13 @@ jobs: echo "📦 缓存文件大小: $(du -sh "$CACHE_FILE" | cut -f1)" echo "📅 缓存文件创建时间: $(stat -c %y "$CACHE_FILE")" - # 显示缓存目录内容 - echo "🔍 /toolcache 目录内容:" - ls -la /toolcache/ | head -10 - - # 创建测试文件验证写入权限 - echo "🧪 创建测试文件验证写入权限..." - TEST_FILE="/toolcache/test_file_$(date +%s).txt" + # 显示缓存目录内容 + echo "🔍 /opt/hostedtoolcache 目录内容:" + ls -la /opt/hostedtoolcache/ | head -10 + + # 创建测试文件验证写入权限 + echo "🧪 创建测试文件验证写入权限..." + TEST_FILE="/opt/hostedtoolcache/test_file_$(date +%s).txt" echo "测试时间: $(date)" > "$TEST_FILE" if [ -f "$TEST_FILE" ]; then echo "✅ 测试文件创建成功: $TEST_FILE" @@ -303,10 +303,10 @@ jobs: echo "当前用户: $(whoami)" echo "用户ID: $(id)" echo "工作目录: $(pwd)" - echo "挂载点信息:" - mount | grep toolcache || echo "未找到toolcache挂载点" - echo "磁盘使用情况:" - df -h /toolcache 2>/dev/null || echo "无法获取/toolcache磁盘信息" + echo "挂载点信息:" + mount | grep hostedtoolcache || echo "未找到hostedtoolcache挂载点" + echo "磁盘使用情况:" + df -h /opt/hostedtoolcache 2>/dev/null || echo "无法获取/opt/hostedtoolcache磁盘信息" echo "---" # 每5秒检查一次缓存状态,持续60秒 @@ -314,11 +314,11 @@ jobs: echo "=== 第 $i 次检查 (第 $((i*5)) 秒) ===" echo "时间: $(date)" - echo "📁 /toolcache 目录详细信息:" - echo "目录权限: $(ls -ld /toolcache 2>/dev/null || echo '无法获取权限')" - echo "目录所有者: $(stat -c '%U:%G' /toolcache 2>/dev/null || echo '无法获取所有者')" - echo "目录内容:" - ls -la /toolcache/ 2>/dev/null | head -10 || echo "无法访问 /toolcache" + echo "📁 /opt/hostedtoolcache 目录详细信息:" + echo "目录权限: $(ls -ld /opt/hostedtoolcache 2>/dev/null || echo '无法获取权限')" + echo "目录所有者: $(stat -c '%U:%G' /opt/hostedtoolcache 2>/dev/null || echo '无法获取所有者')" + echo "目录内容:" + ls -la /opt/hostedtoolcache/ 2>/dev/null | head -10 || echo "无法访问 /opt/hostedtoolcache" if [ -f "$CACHE_FILE" ]; then echo "✅ 缓存文件存在: $CACHE_FILE" @@ -413,7 +413,7 @@ jobs: cp -r dist/* deploy/ echo "📦 部署包已准备完成" - - name: 验证 /toolcache 挂载情况(开始) + - name: 验证 /opt/hostedtoolcache 挂载情况(开始) shell: bash run: | echo "==== [挂载点检查-开始] ====" @@ -421,19 +421,19 @@ jobs: echo "主机名: $(hostname)" echo "当前用户: $(whoami)" echo "工作目录: $(pwd)" - echo "[mount | grep toolcache] 输出:" - mount | grep toolcache || echo "未找到toolcache挂载点" - echo "[df -h /toolcache] 输出:" - df -h /toolcache 2>/dev/null || echo "无法获取/toolcache磁盘信息" - echo "[ls -ld /toolcache] 输出:" - ls -ld /toolcache 2>/dev/null || echo "无法获取/toolcache权限" - echo "[stat /toolcache] 输出:" - stat /toolcache 2>/dev/null || echo "无法获取/toolcache stat" - echo "[ls -lai /toolcache] 输出:" - ls -lai /toolcache 2>/dev/null || echo "无法获取/toolcache内容" + echo "[mount | grep hostedtoolcache] 输出:" + mount | grep hostedtoolcache || echo "未找到hostedtoolcache挂载点" + echo "[df -h /opt/hostedtoolcache] 输出:" + df -h /opt/hostedtoolcache 2>/dev/null || echo "无法获取/opt/hostedtoolcache磁盘信息" + echo "[ls -ld /opt/hostedtoolcache] 输出:" + ls -ld /opt/hostedtoolcache 2>/dev/null || echo "无法获取/opt/hostedtoolcache权限" + echo "[stat /opt/hostedtoolcache] 输出:" + stat /opt/hostedtoolcache 2>/dev/null || echo "无法获取/opt/hostedtoolcache stat" + echo "[ls -lai /opt/hostedtoolcache] 输出:" + ls -lai /opt/hostedtoolcache 2>/dev/null || echo "无法获取/opt/hostedtoolcache内容" echo "==== [挂载点检查-开始] ====" - - name: 验证 /toolcache 挂载情况(保存缓存后) + - name: 验证 /opt/hostedtoolcache 挂载情况(保存缓存后) shell: bash run: | echo "==== [挂载点检查-保存缓存后] ====" @@ -441,16 +441,16 @@ jobs: echo "主机名: $(hostname)" echo "当前用户: $(whoami)" echo "工作目录: $(pwd)" - echo "[mount | grep toolcache] 输出:" - mount | grep toolcache || echo "未找到toolcache挂载点" - echo "[df -h /toolcache] 输出:" - df -h /toolcache 2>/dev/null || echo "无法获取/toolcache磁盘信息" - echo "[ls -ld /toolcache] 输出:" - ls -ld /toolcache 2>/dev/null || echo "无法获取/toolcache权限" - echo "[stat /toolcache] 输出:" - stat /toolcache 2>/dev/null || echo "无法获取/toolcache stat" - echo "[ls -lai /toolcache] 输出:" - ls -lai /toolcache 2>/dev/null || echo "无法获取/toolcache内容" + echo "[mount | grep hostedtoolcache] 输出:" + mount | grep hostedtoolcache || echo "未找到hostedtoolcache挂载点" + echo "[df -h /opt/hostedtoolcache] 输出:" + df -h /opt/hostedtoolcache 2>/dev/null || echo "无法获取/opt/hostedtoolcache磁盘信息" + echo "[ls -ld /opt/hostedtoolcache] 输出:" + ls -ld /opt/hostedtoolcache 2>/dev/null || echo "无法获取/opt/hostedtoolcache权限" + echo "[stat /opt/hostedtoolcache] 输出:" + stat /opt/hostedtoolcache 2>/dev/null || echo "无法获取/opt/hostedtoolcache stat" + echo "[ls -lai /opt/hostedtoolcache] 输出:" + ls -lai /opt/hostedtoolcache 2>/dev/null || echo "无法获取/opt/hostedtoolcache内容" echo "==== [挂载点检查-保存缓存后] ====" # - name: 复制构建产物到目标目录 diff --git a/README.md b/README.md index 5fc0306..e42d63b 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,195 @@ -# Rsbuild project +# Epic UI - 现代化前端项目 -## Setup +## 项目简介 -Install the dependencies: +Epic UI 是一个基于 React + TypeScript + Rsbuild 构建的现代化前端项目,采用 Tailwind CSS 作为样式框架,Ant Design 作为 UI 组件库。 + +## 技术栈 + +- **框架**: React 19.1.0 + TypeScript 5.8.2 +- **构建工具**: Rsbuild 1.3.1 +- **包管理器**: pnpm +- **样式**: Tailwind CSS 4.1.4 +- **UI组件**: Ant Design 5.26.3 +- **路由**: React Router DOM 7.5.0 +- **代码规范**: Biome 1.9.4 + +## 开发环境设置 + +### 安装依赖 ```bash pnpm install ``` -## Get started - -Start the dev server: +### 启动开发服务器 ```bash pnpm dev ``` -Build the app for production: +### 构建生产版本 ```bash pnpm build ``` -Preview the production build locally: +### 预览生产构建 ```bash pnpm preview ``` + +## Gitea Runner NPM 缓存配置 + +### 问题背景 + +在容器化环境中,Gitea Runner 每次构建都需要重新下载 npm 包,导致构建时间过长。通过配置持久化缓存可以显著提升构建效率。 + +### 缓存策略 + +1. **pnpm 缓存**: 缓存 pnpm 全局缓存目录 +2. **node_modules 缓存**: 缓存项目依赖 +3. **构建产物缓存**: 缓存构建输出 + +### 配置步骤 + +#### 1. 配置 Gitea Runner 容器 + +在运行 Gitea Runner 容器时,需要挂载缓存目录: + +```bash +docker run -d \ + --name gitea-runner \ + --restart=always \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /opt/gitea-runner-cache:/opt/hostedtoolcache \ + -v /opt/gitea-runner-data:/data \ + gitea/act_runner:latest +``` + +#### 2. 配置 CI 工作流 + +在 `.gitea/workflows/ci.yaml` 中配置缓存步骤: + +```yaml +- name: 恢复 pnpm 缓存 + shell: bash + run: | + if [ -d "/cache/pnpm-store" ]; then + echo "恢复 pnpm 缓存..." + mkdir -p ~/.pnpm-store + cp -r /cache/pnpm-store/* ~/.pnpm-store/ 2>/dev/null || true + fi + +- name: 安装依赖 + shell: bash + run: | + pnpm install --frozen-lockfile + +- name: 保存 pnpm 缓存 + shell: bash + run: | + echo "保存 pnpm 缓存..." + mkdir -p /cache/pnpm-store + cp -r ~/.pnpm-store/* /cache/pnpm-store/ 2>/dev/null || true +``` + +### 缓存目录说明 + +- `/cache/pnpm-store`: pnpm 全局缓存 +- `/cache/node_modules`: 项目依赖缓存 +- `/cache/build-cache`: 构建产物缓存 + +### 性能优化建议 + +1. **使用国内镜像源**: 配置 `.npmrc` 使用 npmmirror.com +2. **启用离线模式**: 设置 `prefer-offline=true` +3. **并行安装**: 使用 `--parallel` 参数 +4. **缓存清理**: 定期清理过期缓存 + +## 项目结构 + +``` +epic-ui/ +├── src/ # 源代码目录 +├── public/ # 静态资源 +├── .gitea/ # Gitea CI/CD 配置 +├── package.json # 项目配置 +├── pnpm-lock.yaml # 依赖锁定文件 +├── tsconfig.json # TypeScript 配置 +├── rsbuild.config.ts # Rsbuild 构建配置 +└── README.md # 项目文档 +``` + +## 构建和部署 + +### 本地构建 + +```bash +pnpm build +``` + +### CI/CD 构建 + +项目使用 Gitea Actions 进行自动化构建和部署: + +1. 代码推送到 main/master 分支触发构建 +2. 自动安装依赖(使用缓存加速) +3. 构建生产版本 +4. 部署到目标服务器 + +### 构建产物 + +构建完成后,产物位于 `dist/` 目录: +- `index.html`: 主页面 +- `assets/`: 静态资源(JS、CSS、图片等) + +## 开发规范 + +### 代码风格 + +项目使用 Biome 进行代码格式化和检查: + +```bash +# 格式化代码 +pnpm biome format + +# 检查代码 +pnpm biome check +``` + +### Git 提交规范 + +- feat: 新功能 +- fix: 修复问题 +- docs: 文档更新 +- style: 代码格式调整 +- refactor: 代码重构 +- test: 测试相关 +- chore: 构建过程或辅助工具的变动 + +## 故障排除 + +### 常见问题 + +1. **缓存不生效**: 检查挂载目录权限和路径配置 +2. **构建失败**: 检查 Node.js 版本和依赖完整性 +3. **依赖安装慢**: 确认镜像源配置正确 + +### 日志查看 + +```bash +# 查看 Runner 日志 +docker logs gitea-runner + +# 查看构建日志 +# 在 Gitea Web 界面中查看 Actions 日志 +``` + +## 更新日志 + +### v1.0.0 +- 初始项目搭建 +- 配置 Gitea Runner 缓存 +- 实现基础 CI/CD 流程