Просмотр исходного кода

feat: 测试机 Gogs 对接 Drone CI,仅编译打包不部署

同机部署模板与 .drone.yml(web-admin/OA H5/backend 产物),入口端口 18080。

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 1 неделя назад
Родитель
Сommit
a51d4e10aa

+ 67 - 0
.drone.yml

@@ -0,0 +1,67 @@
+# zkxw:仅编译打包,不自动部署测试环境
+# 触发:push / tag
+# 产物:artifacts/*.tar.gz(日志打印 sha256)
+
+kind: pipeline
+type: docker
+name: build-package
+
+concurrency:
+  limit: 1
+
+trigger:
+  event:
+    - push
+    - tag
+
+steps:
+  - name: build-and-package
+    image: node:20-bookworm
+    commands:
+      - set -euo pipefail
+      - mkdir -p artifacts
+      - |
+        echo "[CI] prepare env (tracked .env.docker → .env.test; .env.test is gitignored)"
+        if [ -f web-admin/.env.docker ]; then
+          cp web-admin/.env.docker web-admin/.env.test
+        else
+          echo "missing web-admin/.env.docker" >&2
+          exit 1
+        fi
+        if [ -f mobile-oa-h5/.env.docker ]; then
+          cp mobile-oa-h5/.env.docker mobile-oa-h5/.env.test
+        else
+          echo "missing mobile-oa-h5/.env.docker" >&2
+          exit 1
+        fi
+      - |
+        echo "[CI] web-admin pnpm build:test"
+        corepack enable
+        corepack prepare pnpm@9.15.9 --activate
+        cd web-admin
+        pnpm install --frozen-lockfile
+        pnpm build:test
+        cd ..
+        tar -C web-admin -czf artifacts/web-admin-dist.tar.gz dist
+      - |
+        echo "[CI] mobile-oa-h5 build --mode test"
+        cd mobile-oa-h5
+        npm ci
+        npm run build -- --mode test
+        cd ..
+        tar -C mobile-oa-h5 -czf artifacts/oa-h5-dist.tar.gz dist
+      - |
+        echo "[CI] backend source package"
+        tar -czf artifacts/backend-src.tar.gz \
+          --exclude='backend/.venv' \
+          --exclude='backend/venv' \
+          --exclude='backend/__pycache__' \
+          --exclude='backend/**/__pycache__' \
+          --exclude='backend/logs' \
+          --exclude='backend/.pytest_cache' \
+          --exclude='backend/graphify-out' \
+          backend
+      - |
+        echo "[CI] artifacts checksums"
+        sha256sum artifacts/*.tar.gz
+        ls -lh artifacts/

+ 19 - 2
测试环境部署/README.md

@@ -287,7 +287,21 @@ python3.12 -m venv .venv
 
 ---
 
-## 10. 仓库内相关文件
+## 10. Drone CI(Gogs)
+
+同机 Drone 对接现有 Gogs,仅编译打包、不自动部署。说明与 compose 模板见 **[drone/README.md](drone/README.md)**。
+
+| 项 | 地址 |
+|------|------|
+| Gogs | `http://101.35.245.122:3000` |
+| Drone UI | `http://101.35.245.122:18080` |
+| 流水线 | 仓库根 `.drone.yml`(激活 `wuzilong/zkxw` 后 push 触发) |
+
+服务器部署目录:`/root/drone/`(`.env` 仅机器本地,含 `DRONE_RPC_SECRET`)。
+
+---
+
+## 11. 仓库内相关文件
 
 | 路径 | 说明 |
 |------|------|
@@ -297,11 +311,13 @@ python3.12 -m venv .venv
 | `web-admin/package.json` | `pnpm build:test` |
 | `测试环境部署/zkxw-test-10001.conf` | Nginx 10001 site 配置 |
 | `测试环境部署/deploy_test_env.py` | 日常发版一键脚本(前端打包 + rsync + 重启 + 验收) |
+| `测试环境部署/drone/` | Drone compose 模板与说明 |
+| `.drone.yml` | CI 编译打包流水线 |
 | `docs/superpowers/specs/2026-08-06-test-env-bare-metal-deploy-design.md` | 设计说明 |
 
 ---
 
-## 11. 修订记录
+## 12. 修订记录
 
 | 日期 | 说明 |
 |------|------|
@@ -310,3 +326,4 @@ python3.12 -m venv .venv
 | 2026-08-06 | 裸机部署 10001/10002 于 101.35.245.122 |
 | 2026-08-06 | 新增 `deploy_test_env.py` 日常发版脚本 |
 | 2026-08-10 | 启用 `www.chengyantek.cn` HTTPS(443)+ HTTP→HTTPS;MinIO 同域 `/minio/zkxw` |
+| 2026-10-23 | 新增同机 Drone CI(`:18080`)对接 Gogs;仓库 `.drone.yml` 仅编译打包 |

+ 11 - 0
测试环境部署/drone/.env.example

@@ -0,0 +1,11 @@
+# 复制为 .env 后填写(.env 勿提交 git、勿放进仓库同步)
+# cp .env.example .env
+
+DRONE_RPC_SECRET=replace-with-openssl-rand-hex-32
+DRONE_GOGS_SERVER=http://101.35.245.122:3000
+DRONE_SERVER_HOST=101.35.245.122:18080
+DRONE_SERVER_PROTO=http
+DRONE_RPC_PROTO=http
+DRONE_RPC_HOST=drone:80
+DRONE_RUNNER_CAPACITY=1
+DRONE_RUNNER_NAME=zkxw-test-1

+ 66 - 0
测试环境部署/drone/README.md

@@ -0,0 +1,66 @@
+# 测试机 Drone CI(对接 Gogs)
+
+> 目标机:`101.35.245.122`  
+> Gogs:`http://101.35.245.122:3000`(已有)  
+> Drone UI:`http://101.35.245.122:18080`(云安全组未开 8080,改用已放行的 18080)  
+> 范围:编译打包 artifact,**不**自动部署到 `/root/zkxw`
+
+## 1. 部署(在测试机)
+
+```bash
+mkdir -p /root/drone
+# 从本仓库同步模板,或手工 scp 本目录
+cp docker-compose.yml .env.example /root/drone/
+cd /root/drone
+cp .env.example .env
+# 生成共享密钥
+sed -i "s/replace-with-openssl-rand-hex-32/$(openssl rand -hex 32)/" .env
+docker compose pull
+docker compose up -d
+docker compose ps
+docker logs drone-runner 2>&1 | tail -20
+# 期望看到:successfully pinged the remote server
+```
+
+云安全组 / 主机防火墙放行 **TCP 18080**(本方案默认端口;勿用未放行的 8080)。
+
+## 2. 登录与激活仓库
+
+1. 浏览器打开 `http://101.35.245.122:18080`
+2. 使用 **Gogs 用户名/密码** 登录(Gogs 无 OAuth)
+3. Sync 仓库 → 激活 `wuzilong/zkxw`
+4. 在 Gogs 该仓 **Settings → Webhooks** 确认存在 Drone 回调,例如:  
+   `http://101.35.245.122:18080/hook`
+
+云安全组 / 本机 YJ 防火墙需放行 **TCP 18080**(本机已按此端口部署)。
+
+## 3. 流水线
+
+仓库根目录 [`.drone.yml`](../../.drone.yml):
+
+- `web-admin`:`pnpm build:test` → `artifacts/web-admin-dist.tar.gz`
+- `mobile-oa-h5`:`npm run build -- --mode test` → `artifacts/oa-h5-dist.tar.gz`
+- `backend`:源码打包(排除 venv/logs)→ `artifacts/backend-src.tar.gz`
+
+因 `.env.test` 未入库,流水线构建前会用已跟踪的 `.env.docker` 复制为 `.env.test`(仅保证能编过;若需与线上测试配置一致,可在 Drone 仓库 Secrets 中自行注入后再 `printf` 写入)。
+
+**不会** rsync、不会执行 `start-test.sh`。
+
+## 4. 日常运维
+
+```bash
+cd /root/drone
+docker compose ps
+docker compose logs -f --tail=100 drone
+docker compose logs -f --tail=100 drone-runner
+docker compose restart
+docker compose down    # 停止(保留 volume drone-data)
+```
+
+## 5. 验收
+
+```bash
+curl -sI http://101.35.245.122:18080 | head -5
+curl -sI http://101.35.245.122:3000 | head -5
+# push 到 wuzilong/zkxw 或在 Drone UI 点 Rebuild,构建应为绿色
+```

+ 53 - 0
测试环境部署/drone/docker-compose.yml

@@ -0,0 +1,53 @@
+# Drone CI(对接本机 Gogs)— 部署到测试机 /root/drone/
+# 用法:
+#   cp .env.example .env   # 填写 DRONE_RPC_SECRET
+#   docker compose up -d
+#
+# 访问:http://101.35.245.122:8080 (用 Gogs 用户名/密码登录)
+# Gogs:http://101.35.245.122:3000
+# Runner 不对外暴露端口(避免与 Gogs :3000 冲突)
+
+services:
+  drone:
+    image: drone/drone:2
+    container_name: drone
+    restart: always
+    ports:
+      # 云安全组未放行 8080;18080 已在主机防火墙放行且外网可达
+      - '18080:80'
+    volumes:
+      - drone-data:/data
+    environment:
+      DRONE_AGENTS_ENABLED: 'true'
+      DRONE_GOGS_SERVER: ${DRONE_GOGS_SERVER:-http://101.35.245.122:3000}
+      DRONE_GOGS_SKIP_VERIFY: ${DRONE_GOGS_SKIP_VERIFY:-false}
+      DRONE_RPC_SECRET: ${DRONE_RPC_SECRET}
+      DRONE_SERVER_HOST: ${DRONE_SERVER_HOST:-101.35.245.122:8080}
+      DRONE_SERVER_PROTO: ${DRONE_SERVER_PROTO:-http}
+      DRONE_GIT_ALWAYS_AUTH: ${DRONE_GIT_ALWAYS_AUTH:-false}
+    # 容器访问宿主机 Gogs:把公网 IP 指回宿主机,避免云主机 hairpin 失败
+    extra_hosts:
+      - '101.35.245.122:host-gateway'
+      - 'host.docker.internal:host-gateway'
+
+  runner:
+    image: drone/drone-runner-docker:1
+    container_name: drone-runner
+    restart: always
+    depends_on:
+      - drone
+    volumes:
+      - /var/run/docker.sock:/var/run/docker.sock
+    environment:
+      DRONE_RPC_PROTO: ${DRONE_RPC_PROTO:-http}
+      # 同一 compose 网络内走服务名;勿映射 runner:3000
+      DRONE_RPC_HOST: ${DRONE_RPC_HOST:-drone:80}
+      DRONE_RPC_SECRET: ${DRONE_RPC_SECRET}
+      DRONE_RUNNER_CAPACITY: ${DRONE_RUNNER_CAPACITY:-1}
+      DRONE_RUNNER_NAME: ${DRONE_RUNNER_NAME:-zkxw-test-1}
+    extra_hosts:
+      - '101.35.245.122:host-gateway'
+      - 'host.docker.internal:host-gateway'
+
+volumes:
+  drone-data: