Compare commits
2 Commits
6b65e1bcfa
...
d8f30e8362
| Author | SHA1 | Date | |
|---|---|---|---|
| d8f30e8362 | |||
| 567613aa6b |
@ -2,8 +2,10 @@
|
||||
# Duoqi API - 双分支工作流(develop → main)
|
||||
#
|
||||
# 工作流:
|
||||
# develop push → quality → test → build → 自动部署测试环境
|
||||
# main push → quality → test → build → 手动确认部署生产环境
|
||||
# develop push → quality → test → 构建并自动部署测试环境
|
||||
# main push → quality → test → 构建并手动确认部署生产环境
|
||||
#
|
||||
# 注意:单服务器架构,构建后直接部署,无需 artifact 传递
|
||||
|
||||
name: CI/CD Pipeline
|
||||
|
||||
@ -44,70 +46,21 @@ jobs:
|
||||
- name: Run tests
|
||||
run: bun run test
|
||||
|
||||
# ==================== 构建测试镜像 ====================
|
||||
build-test:
|
||||
name: Build Test Image
|
||||
# ==================== 构建并部署测试环境(develop 自动触发)====================
|
||||
build-and-deploy-test:
|
||||
name: Build & Deploy Test
|
||||
runs-on: ubuntu-latest
|
||||
needs: [quality, test]
|
||||
if: github.ref == 'refs/heads/develop'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build test image
|
||||
run: |
|
||||
docker build --build-arg NODE_ENV=test -t duoqi-api:test .
|
||||
mkdir -p /tmp/images
|
||||
docker save duoqi-api:test -o /tmp/images/duoqi-api-test.tar
|
||||
|
||||
- name: Upload image artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: docker-images-test
|
||||
path: /tmp/images/
|
||||
retention-days: 1
|
||||
|
||||
# ==================== 构建生产镜像 ====================
|
||||
build-prod:
|
||||
name: Build Production Image
|
||||
runs-on: ubuntu-latest
|
||||
needs: [quality, test]
|
||||
if: github.ref == 'refs/heads/main'
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build production image
|
||||
run: |
|
||||
docker build -t duoqi-api:prod .
|
||||
mkdir -p /tmp/images
|
||||
docker save duoqi-api:prod -o /tmp/images/duoqi-api-prod.tar
|
||||
|
||||
- name: Upload image artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: docker-images-prod
|
||||
path: /tmp/images/
|
||||
retention-days: 1
|
||||
|
||||
# ==================== 部署到测试环境(develop push 自动触发) ====================
|
||||
deploy-test:
|
||||
name: Deploy to Test
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-test
|
||||
if: github.ref == 'refs/heads/develop'
|
||||
environment:
|
||||
name: test
|
||||
url: http://test-api.duoqi.me
|
||||
steps:
|
||||
- name: Download image artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: docker-images-test
|
||||
path: /tmp/images/
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Load Docker image
|
||||
run: docker load -i /tmp/images/duoqi-api-test.tar
|
||||
- name: Build test image
|
||||
run: docker build --build-arg NODE_ENV=test -t duoqi-api:test .
|
||||
|
||||
- name: Deploy test environment
|
||||
run: |
|
||||
@ -128,24 +81,21 @@ jobs:
|
||||
echo "Test environment health check failed"
|
||||
exit 1
|
||||
|
||||
# ==================== 部署到生产环境(main push,手动确认) ====================
|
||||
deploy-prod:
|
||||
name: Deploy to Production
|
||||
# ==================== 构建并部署生产环境(main 手动确认)====================
|
||||
build-and-deploy-prod:
|
||||
name: Build & Deploy Production
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-prod
|
||||
needs: [quality, test]
|
||||
if: github.ref == 'refs/heads/main'
|
||||
environment:
|
||||
name: production
|
||||
url: https://api.duoqi.me
|
||||
steps:
|
||||
- name: Download image artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: docker-images-prod
|
||||
path: /tmp/images/
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Load Docker image
|
||||
run: docker load -i /tmp/images/duoqi-api-prod.tar
|
||||
- name: Build production image
|
||||
run: docker build -t duoqi-api:prod .
|
||||
|
||||
- name: Deploy production
|
||||
run: |
|
||||
@ -178,6 +128,4 @@ jobs:
|
||||
|
||||
- name: Cleanup
|
||||
if: always()
|
||||
run: |
|
||||
docker image prune -f
|
||||
rm -rf /tmp/images
|
||||
run: docker image prune -f
|
||||
|
||||
@ -287,27 +287,36 @@ cd /opt/gitea && docker compose up -d
|
||||
|
||||
#### 安装 Act Runner(CI/CD 执行器)
|
||||
|
||||
> **国内网络关键配置**:Gitea Act Runner 使用 Docker 执行器,需要解决三个网络问题:
|
||||
> **国内网络关键配置**:Gitea Act Runner 使用 Docker 执行器,需要解决以下问题:
|
||||
> 1. Docker Hub 镜像拉取 → 通过 Docker 镜像加速解决(已在服务器初始化配置)
|
||||
> 2. GitHub Actions 拉取 → 通过 `github_mirror` 配置从 gitea.com 镜像解决
|
||||
> 3. 容器访问 Gitea API → 通过 `--network host` 让容器共享宿主机网络
|
||||
> 3. 容器访问 Gitea API → 通过 `network: host` 让容器共享宿主机网络
|
||||
> 4. Job 容器执行 docker 命令 → 挂载宿主机 Docker socket,镜像内置 Docker CLI
|
||||
|
||||
##### 1. 构建 Runner 自定义镜像
|
||||
|
||||
> `oven/bun:latest` 不包含 git,`actions/checkout` 会回退到 REST API 下载代码,
|
||||
> 但 GitHub 风格的 REST API URL(`/tarball/{ref}`)与 Gitea(`/archive/{ref}.tar.gz`)不兼容。
|
||||
> 因此需要构建预装 git 的自定义镜像,避免每次 CI 安装。
|
||||
> `oven/bun` 不包含 git 和 docker CLI,需要构建自定义镜像:
|
||||
> - **git**:`actions/checkout` 需要,否则会回退到 REST API(GitHub 与 Gitea URL 格式不兼容)
|
||||
> - **docker CLI**:CI 中执行 `docker build` 等命令需要,通过 socket 连接宿主机 Docker daemon
|
||||
> - **固定版本**:使用 Bun 1.3 而非 latest,确保 CI 环境可复现
|
||||
|
||||
```bash
|
||||
# 创建 Dockerfile
|
||||
cat > /opt/runner-image/Dockerfile << 'EOF'
|
||||
FROM oven/bun:latest
|
||||
FROM oven/bun:1.3
|
||||
RUN sed -i 's|deb.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list.d/debian.sources \
|
||||
&& apt-get update && apt-get install -y git && rm -rf /var/lib/apt/lists/*
|
||||
&& apt-get update \
|
||||
&& apt-get install -y git docker.io \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
EOF
|
||||
|
||||
# 构建镜像(使用阿里云 Debian 镜像源加速)
|
||||
docker build -t duoqi-runner:bun-git /opt/runner-image
|
||||
|
||||
# 验证镜像包含所需工具
|
||||
docker run --rm duoqi-runner:bun-git bun --version
|
||||
docker run --rm duoqi-runner:bun-git git --version
|
||||
docker run --rm duoqi-runner:bun-git docker --version
|
||||
```
|
||||
|
||||
##### 2. 安装并注册 Runner
|
||||
@ -370,6 +379,9 @@ ExecStart=/usr/local/bin/act_runner daemon --config /opt/act-runner/config.yaml
|
||||
Restart=always
|
||||
Environment=HOME=/root
|
||||
|
||||
# 关键:挂载 Docker socket,让 job 容器能访问宿主机的 Docker daemon
|
||||
BindPaths=/var/run/docker.sock:/var/run/docker.sock
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
@ -551,7 +563,7 @@ develop 分支(开发测试) main 分支(生产发布)
|
||||
└─────┬─────┘ └─────┬─────┘
|
||||
▼ ▼
|
||||
┌───────────┐ ┌───────────┐
|
||||
│ test │ ← 单元测试 + 覆盖率 │ test │ ← 单元测试 + 覆盖率
|
||||
│ test │ ← 单元测试 │ test │ ← 单元测试
|
||||
└─────┬─────┘ └─────┬─────┘
|
||||
▼ ▼
|
||||
┌────────────┐ ┌────────────┐
|
||||
@ -608,9 +620,11 @@ git push origin main
|
||||
| 测试环境使用 Docker profiles | 按需启停,节省内存 |
|
||||
| 生产部署手动确认 | 防止误操作,确保人工验证后才上线 |
|
||||
| 使用 Gitea Actions | 兼容 GitHub Actions 语法,学习成本低 |
|
||||
| Runner 使用 `--network host` | 容器共享宿主机网络,解决容器无法访问 Gitea 的问题 |
|
||||
| Runner 使用 `network: host` | 容器共享宿主机网络,解决容器无法访问 Gitea 的问题 |
|
||||
| Runner 使用 `github_mirror` | 从 gitea.com 镜像拉取 Actions,解决国内无法访问 GitHub 的问题 |
|
||||
| 自定义 Runner 镜像(bun + git) | 避免 checkout REST API 与 Gitea 不兼容的问题,跳过每次安装 |
|
||||
| 自定义 Runner 镜像(bun + git + docker CLI) | 避免 checkout REST API 不兼容,支持 CI 中执行 docker 命令 |
|
||||
| Runner 挂载 Docker socket | Job 容器通过 socket 访问宿主机 Docker daemon,执行构建操作 |
|
||||
| 固定 Bun 版本(1.3) | 确保 CI 环境可复现,避免 latest 版本变化导致意外失败 |
|
||||
|
||||
### 部署操作
|
||||
|
||||
@ -1099,6 +1113,6 @@ docker compose up -d api-prod
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v5.1.0 (双分支工作流 + 国内网络适配)
|
||||
**文档版本**: v5.2.0 (双分支工作流 + 国内网络适配 + Docker 执行器完善)
|
||||
**最后更新**: 2026-04-17
|
||||
**维护者**: Duoqi Team
|
||||
|
||||
Loading…
Reference in New Issue
Block a user