feat: improve Docker deployment and release workflows

- Add WeasyPrint system dependencies with Chinese font support
- Update requirements.txt with all dependencies
- Fix docker-compose.yml network configuration
- Update GitHub Actions release workflow for frontend-backend architecture
- Update release script for new project structure
- Support multi-arch Docker builds (amd64, arm64)
This commit is contained in:
lintsinghua 2025-11-28 20:43:26 +08:00
parent 9054f0d2c5
commit 9d2d9367b2
6 changed files with 160 additions and 63 deletions

View File

@ -6,7 +6,7 @@ on:
workflow_dispatch:
inputs:
version:
description: '版本号 (例如: v1.0.0)'
description: '版本号 (例如: v2.0.0)'
required: true
type: string
prerelease:
@ -36,29 +36,37 @@ jobs:
with:
fetch-depth: 0
# 2. 设置 Node.js 环境
# 2. 设置 Node.js 环境(用于前端构建)
- name: 设置 Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
node-version: '20'
cache: 'pnpm'
cache-dependency-path: frontend/pnpm-lock.yaml
# 3. 安装 pnpm
- name: 安装 pnpm
run: npm install -g pnpm
# 4. 安装依赖
- name: 安装依赖
run: pnpm install --no-frozen-lockfile
# 4. 安装前端依赖
- name: 安装前端依赖
working-directory: ./frontend
run: pnpm install --frozen-lockfile
# 5. 构建前端项目
- name: 构建项目
- name: 构建前端项目
working-directory: ./frontend
run: pnpm build
env:
# 这里可以添加构建时需要的环境变量
VITE_USE_LOCAL_DB: 'true'
# 6. 确定版本号
# 6. 设置 Python 环境(用于后端)
- name: 设置 Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
# 7. 确定版本号
- name: 确定版本号
id: version
run: |
@ -69,20 +77,43 @@ jobs:
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
echo "IS_PRERELEASE=false" >> $GITHUB_OUTPUT
fi
VERSION_NO_V="${VERSION#v}"
echo "VERSION_NO_V=$VERSION_NO_V" >> $GITHUB_OUTPUT
# 7. 打包构建产物
# 8. 打包构建产物
- name: 打包构建产物
run: |
# 创建发布目录
mkdir -p release
# 打包前端构建产物
tar -czf release/xcode-reviewer-frontend-${{ steps.version.outputs.VERSION }}.tar.gz -C dist .
tar -czf release/xcodereviewer-frontend-${{ steps.version.outputs.VERSION }}.tar.gz -C frontend/dist .
# 打包后端源码
tar -czf release/xcodereviewer-backend-${{ steps.version.outputs.VERSION }}.tar.gz \
--exclude=backend/.venv \
--exclude=backend/.env \
--exclude=backend/__pycache__ \
--exclude=backend/uploads \
backend/
# 打包 Docker 配置文件
tar -czf release/xcodereviewer-docker-${{ steps.version.outputs.VERSION }}.tar.gz \
docker-compose.yml \
Dockerfile \
nginx.conf \
backend/Dockerfile \
frontend/Dockerfile \
backend/env.example \
frontend/.env.example
# 打包完整源码(包括配置文件)
tar -czf release/xcode-reviewer-source-${{ steps.version.outputs.VERSION }}.tar.gz \
--exclude=node_modules \
--exclude=dist \
tar -czf release/xcodereviewer-source-${{ steps.version.outputs.VERSION }}.tar.gz \
--exclude=frontend/node_modules \
--exclude=frontend/dist \
--exclude=backend/.venv \
--exclude=backend/.env \
--exclude=backend/uploads \
--exclude=.git \
--exclude=release \
.
@ -92,7 +123,7 @@ jobs:
sha256sum * > checksums.txt
cd ..
# 8. 生成更新日志
# 9. 生成更新日志
- name: 生成更新日志
id: changelog
run: |
@ -110,15 +141,28 @@ jobs:
echo "" >> CHANGELOG.md
echo "" >> CHANGELOG.md
echo "## 下载说明" >> CHANGELOG.md
echo "## 📦 下载说明" >> CHANGELOG.md
echo "" >> CHANGELOG.md
echo "- \`xcode-reviewer-frontend-*.tar.gz\`: 前端构建产物(用于部署)" >> CHANGELOG.md
echo "- \`xcode-reviewer-source-*.tar.gz\`: 完整源码包" >> CHANGELOG.md
echo "### 构建产物" >> CHANGELOG.md
echo "- \`xcodereviewer-frontend-*.tar.gz\`: 前端构建产物(用于生产部署)" >> CHANGELOG.md
echo "- \`xcodereviewer-backend-*.tar.gz\`: 后端源码包" >> CHANGELOG.md
echo "- \`xcodereviewer-docker-*.tar.gz\`: Docker 配置文件" >> CHANGELOG.md
echo "- \`xcodereviewer-source-*.tar.gz\`: 完整源码包" >> CHANGELOG.md
echo "- \`checksums.txt\`: 文件校验和" >> CHANGELOG.md
echo "" >> CHANGELOG.md
echo "### Docker 镜像" >> CHANGELOG.md
echo "- Frontend: \`ghcr.io/${{ github.repository_owner }}/xcodereviewer-frontend:${{ steps.version.outputs.VERSION }}\`" >> CHANGELOG.md
echo "- Backend: \`ghcr.io/${{ github.repository_owner }}/xcodereviewer-backend:${{ steps.version.outputs.VERSION }}\`" >> CHANGELOG.md
echo "" >> CHANGELOG.md
echo "### 快速部署" >> CHANGELOG.md
echo "\`\`\`bash" >> CHANGELOG.md
echo "# 使用 Docker Compose 部署" >> CHANGELOG.md
echo "docker-compose up -d" >> CHANGELOG.md
echo "\`\`\`" >> CHANGELOG.md
# 9. 创建 GitHub Release
# 10. 创建 GitHub Release
- name: 创建 Release
uses: softprops/action-gh-release@v1
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.version.outputs.VERSION }}
name: Release ${{ steps.version.outputs.VERSION }}
@ -131,7 +175,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# 10. 登录 GitHub Container Registry
# 11. 登录 GitHub Container Registry
- name: 登录到 GitHub Container Registry
uses: docker/login-action@v3
with:
@ -139,41 +183,51 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# 11. 设置 QEMU用于多架构构建
# 12. 设置 QEMU用于多架构构建
- name: 设置 QEMU
uses: docker/setup-qemu-action@v3
# 12. 设置 Docker Buildx
# 13. 设置 Docker Buildx
- name: 设置 Docker Buildx
uses: docker/setup-buildx-action@v3
# 13. 构建并推送 Docker 镜像(多架构
- name: 构建并推送 Docker 镜像
# 14. 构建并推送前端 Docker 镜像(生产环境 Nginx
- name: 构建并推送前端 Docker 镜像
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
platforms: linux/amd64,linux/arm64,linux/arm/v7
platforms: linux/amd64,linux/arm64
tags: |
ghcr.io/${{ github.repository_owner }}/xcodereviewer:${{ steps.version.outputs.VERSION }}
ghcr.io/${{ github.repository_owner }}/xcodereviewer:latest
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
VITE_USE_LOCAL_DB=true
ghcr.io/${{ github.repository_owner }}/xcodereviewer-frontend:${{ steps.version.outputs.VERSION }}
ghcr.io/${{ github.repository_owner }}/xcodereviewer-frontend:latest
cache-from: type=gha,scope=frontend
cache-to: type=gha,mode=max,scope=frontend
# 14. 更新 package.json 版本号(可选)
- name: 更新 package.json 版本
if: github.event_name == 'workflow_dispatch'
# 15. 构建并推送后端 Docker 镜像
- name: 构建并推送后端 Docker 镜像
uses: docker/build-push-action@v5
with:
context: ./backend
file: ./backend/Dockerfile
push: true
platforms: linux/amd64,linux/arm64
tags: |
ghcr.io/${{ github.repository_owner }}/xcodereviewer-backend:${{ steps.version.outputs.VERSION }}
ghcr.io/${{ github.repository_owner }}/xcodereviewer-backend:latest
cache-from: type=gha,scope=backend
cache-to: type=gha,mode=max,scope=backend
# 16. 更新 README 中的版本号
- name: 更新 README 版本号
if: github.event_name == 'push'
run: |
VERSION="${{ steps.version.outputs.VERSION }}"
VERSION_NO_V="${VERSION#v}"
npm version $VERSION_NO_V --no-git-tag-version
VERSION="${{ steps.version.outputs.VERSION_NO_V }}"
sed -i "s/version-[0-9]*\.[0-9]*\.[0-9]*/version-$VERSION/g" README.md
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add package.json
git commit -m "chore: bump version to $VERSION" || true
git add README.md
git commit -m "docs: update README version to $VERSION" || true
git push origin HEAD:main || true

View File

@ -33,7 +33,7 @@ jobs:
if [ -z "$LAST_TAG" ]; then
echo "has_changes=true" >> $GITHUB_OUTPUT
echo "version=v0.1.0" >> $GITHUB_OUTPUT
echo "version=v2.0.0" >> $GITHUB_OUTPUT
else
# 检查自上次 tag 以来是否有新的提交
COMMITS_SINCE_TAG=$(git rev-list $LAST_TAG..HEAD --count)
@ -71,7 +71,9 @@ jobs:
- name: 触发发布
if: steps.check.outputs.has_changes == 'true'
run: |
echo "新版本 ${{ steps.check.outputs.version }} 已创建,将触发发布流程"
echo "请查看 Release 工作流的执行情况"
echo "✅ 新版本 ${{ steps.check.outputs.version }} 已创建"
echo "🚀 Release 工作流将自动开始构建和发布"
echo "📦 将发布以下组件:"
echo " - 前端 Docker 镜像"
echo " - 后端 Docker 镜像"
echo " - 构建产物和源码包"

View File

@ -4,12 +4,30 @@ WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV PIP_NO_CACHE_DIR=1
ENV PIP_DISABLE_PIP_VERSION_CHECK=1
# 安装系统依赖
RUN apt-get update && apt-get install -y --no-install-recommends \
# 安装系统依赖(包含 WeasyPrint 所需的库和中文字体支持)
RUN for i in 1 2 3; do \
apt-get update && \
apt-get install -y --no-install-recommends \
gcc \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
# WeasyPrint 依赖
libpango-1.0-0 \
libpangoft2-1.0-0 \
libcairo2 \
libgdk-pixbuf2.0-0 \
libffi-dev \
shared-mime-info \
# 字体支持(中文)
fonts-noto-cjk \
fonts-noto-cjk-extra \
fontconfig \
&& fc-cache -fv \
&& rm -rf /var/lib/apt/lists/* \
&& break || sleep 5; \
done
# 复制依赖文件
COPY pyproject.toml .
@ -31,3 +49,4 @@ EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

View File

@ -9,5 +9,10 @@ passlib[bcrypt]
python-jose[cryptography]
python-multipart
httpx
email-validator
greenlet
bcrypt<5.0.0
litellm>=1.0.0
reportlab>=4.0.0
weasyprint>=66.0
jinja2>=3.1.6

View File

@ -1,5 +1,3 @@
version: '3.8'
services:
db:
image: postgres:15-alpine
@ -16,6 +14,8 @@ services:
interval: 5s
timeout: 5s
retries: 5
networks:
- xcodereviewer-network
backend:
build:
@ -33,6 +33,8 @@ services:
db:
condition: service_healthy
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
networks:
- xcodereviewer-network
frontend:
build:
@ -43,10 +45,16 @@ services:
ports:
- "5173:5173"
environment:
- VITE_API_BASE_URL=http://localhost:8000/api/v1
- VITE_API_BASE_URL=http://backend:8000/api/v1
depends_on:
- backend
command: npm run dev -- --host
networks:
- xcodereviewer-network
networks:
xcodereviewer-network:
driver: bridge
volumes:
postgres_data:

View File

@ -40,8 +40,13 @@ if [ -n "$(git status --porcelain)" ]; then
fi
fi
# 获取当前版本号
CURRENT_VERSION=$(node -p "require('./package.json').version")
# 获取当前版本号(从前端项目)
if [ -f "frontend/package.json" ]; then
CURRENT_VERSION=$(node -p "require('./frontend/package.json').version")
else
print_error "找不到 frontend/package.json 文件"
exit 1
fi
print_info "当前版本: v$CURRENT_VERSION"
# 解析版本号
@ -94,13 +99,17 @@ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 0
fi
# 更新 package.json
print_info "更新 package.json..."
# 更新前端 package.json
print_info "更新前端 package.json..."
cd frontend
npm version "$NEW_VERSION" --no-git-tag-version
cd ..
# 提交更改
print_info "提交版本更改..."
git add package.json package-lock.json 2>/dev/null || true
git add frontend/package.json frontend/package-lock.json 2>/dev/null || true
git add frontend/pnpm-lock.yaml 2>/dev/null || true
git add README.md 2>/dev/null || true
git commit -m "chore: bump version to v$NEW_VERSION" || true
# 创建 tag