From ed0a44851d56c7962e9b8cd8a58e8b9ae18e23b7 Mon Sep 17 00:00:00 2001 From: CHE LIANG ZHAO Date: Mon, 26 Jan 2026 17:21:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20Gitea=20Actions=20?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E9=83=A8=E7=BD=B2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/deploy.yaml | 67 ++++++++++++++++++++++++++++++++++++ deploy.sh | 62 +++++++++++++++++++++++++++++++++ docker-compose.runner.yaml | 38 ++++++++++++++++++++ runner/.env.example | 3 ++ runner/config.yaml | 48 ++++++++++++++++++++++++++ 5 files changed, 218 insertions(+) create mode 100644 .gitea/workflows/deploy.yaml create mode 100644 deploy.sh create mode 100644 docker-compose.runner.yaml create mode 100644 runner/.env.example create mode 100644 runner/config.yaml diff --git a/.gitea/workflows/deploy.yaml b/.gitea/workflows/deploy.yaml new file mode 100644 index 0000000..deb6866 --- /dev/null +++ b/.gitea/workflows/deploy.yaml @@ -0,0 +1,67 @@ +# BillAI 自动部署工作流 +# 当 master 分支有 push 时自动触发部署 + +name: Deploy BillAI + +on: + push: + branches: + - master + +jobs: + deploy: + name: Deploy to Production + runs-on: self-hosted + steps: + - name: Checkout code + run: | + echo "=== 拉取最新代码 ===" + cd ${{ vars.DEPLOY_PATH }} + git fetch origin master + git reset --hard origin/master + echo "当前版本: $(git log -1 --format='%h %s')" + + - name: Build and deploy + run: | + echo "=== 构建并部署服务 ===" + cd ${{ vars.DEPLOY_PATH }} + docker compose up -d --build --remove-orphans + + - name: Cleanup + run: | + echo "=== 清理旧镜像 ===" + docker image prune -f + + - name: Health check + run: | + echo "=== 健康检查 ===" + echo "等待服务启动..." + sleep 15 + + # 通过 Docker 健康检查状态判断(不依赖端口暴露) + check_container() { + local name=$1 + local container=$2 + local status=$(docker inspect --format='{{.State.Health.Status}}' "$container" 2>/dev/null) + if [ "$status" = "healthy" ]; then + echo "✓ $name 服务正常" + return 0 + else + echo "✗ $name 服务异常 (状态: $status)" + return 1 + fi + } + + FAILED=0 + check_container "Web" "billai-web" || FAILED=1 + check_container "Server" "billai-server" || FAILED=1 + check_container "Analyzer" "billai-analyzer" || FAILED=1 + check_container "MongoDB" "billai-mongodb" || FAILED=1 + + if [ $FAILED -eq 0 ]; then + echo "=== 部署成功 ===" + else + echo "=== 部署失败:部分服务异常 ===" + docker compose ps + exit 1 + fi diff --git a/deploy.sh b/deploy.sh new file mode 100644 index 0000000..69fd567 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# BillAI 部署脚本 +# 用于手动部署或 Gitea Actions 自动部署 + +set -e + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +echo -e "${GREEN}=== BillAI 部署开始 ===${NC}" +echo "时间: $(date '+%Y-%m-%d %H:%M:%S')" + +# 获取脚本所在目录 +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +echo -e "\n${YELLOW}[1/4] 拉取最新代码${NC}" +git fetch origin master +git reset --hard origin/master +echo "当前版本: $(git log -1 --format='%h %s')" + +echo -e "\n${YELLOW}[2/4] 构建并部署服务${NC}" +docker compose up -d --build --remove-orphans + +echo -e "\n${YELLOW}[3/4] 清理旧镜像${NC}" +docker image prune -f + +echo -e "\n${YELLOW}[4/4] 健康检查${NC}" +echo "等待服务启动..." +sleep 15 + +# 检查服务状态(通过 Docker 健康检查状态) +check_service() { + local name=$1 + local container=$2 + local status=$(docker inspect --format='{{.State.Health.Status}}' "$container" 2>/dev/null) + if [ "$status" = "healthy" ]; then + echo -e " ${GREEN}✓${NC} $name 服务正常" + return 0 + else + echo -e " ${RED}✗${NC} $name 服务异常 (状态: $status)" + return 1 + fi +} + +FAILED=0 +check_service "Web" "billai-web" || FAILED=1 +check_service "Server" "billai-server" || FAILED=1 +check_service "Analyzer" "billai-analyzer" || FAILED=1 +check_service "MongoDB" "billai-mongodb" || FAILED=1 + +if [ $FAILED -eq 0 ]; then + echo -e "\n${GREEN}=== 部署成功 ===${NC}" + exit 0 +else + echo -e "\n${RED}=== 部署失败:部分服务异常 ===${NC}" + docker compose ps + exit 1 +fi diff --git a/docker-compose.runner.yaml b/docker-compose.runner.yaml new file mode 100644 index 0000000..8ddb48d --- /dev/null +++ b/docker-compose.runner.yaml @@ -0,0 +1,38 @@ +# Gitea Actions Runner - 自动部署 +# +# 使用方法: +# 1. 在 Gitea 仓库获取 Runner Token +# 访问:https://git.fadinglight.cn/clz/billai/settings/actions/runners +# 点击 "Create new Runner" 复制 Token +# +# 2. 创建 .env 文件或设置环境变量 +# echo "GITEA_RUNNER_REGISTRATION_TOKEN=你的Token" > runner/.env +# +# 3. 启动 Runner +# docker compose -f docker-compose.runner.yaml up -d +# +# 4. 在 Gitea 仓库添加变量 +# 访问:https://git.fadinglight.cn/clz/billai/settings/actions/variables +# 添加 DEPLOY_PATH = /你的项目路径 + +services: + runner: + image: gitea/act_runner:latest + container_name: billai-runner + restart: unless-stopped + env_file: + - ./runner/.env + environment: + GITEA_INSTANCE_URL: "https://git.fadinglight.cn" + GITEA_RUNNER_NAME: "billai-runner" + GITEA_RUNNER_LABELS: "self-hosted:host,ubuntu-latest:host" + CONFIG_FILE: /config.yaml + volumes: + # Runner 配置文件 + - ./runner/config.yaml:/config.yaml + # Runner 数据持久化 + - ./runner/data:/data + # Docker socket - 用于在宿主机执行 docker 命令 + - /var/run/docker.sock:/var/run/docker.sock + # 项目目录 - 用于执行部署脚本 + - .:/workspace/billai diff --git a/runner/.env.example b/runner/.env.example new file mode 100644 index 0000000..54c114d --- /dev/null +++ b/runner/.env.example @@ -0,0 +1,3 @@ +# Gitea Runner 配置 +# 从 Gitea 仓库获取 Token:Settings -> Actions -> Runners -> Create new Runner +GITEA_RUNNER_REGISTRATION_TOKEN=你的Token diff --git a/runner/config.yaml b/runner/config.yaml new file mode 100644 index 0000000..e6f33f3 --- /dev/null +++ b/runner/config.yaml @@ -0,0 +1,48 @@ +# Gitea Actions Runner 配置 +# 文档: https://docs.gitea.com/usage/actions/act-runner + +log: + # 日志级别: debug, info, warn, error + level: info + +runner: + # Runner 注册信息存储文件 + file: .runner + # 同时运行的任务数量 + capacity: 1 + # 环境变量传递给 job + envs: {} + # 任务超时时间 + timeout: 1h + # 关机超时时间 + shutdown_timeout: 3h + # 是否获取远程任务时不进行 TLS 验证(不推荐) + insecure: false + # 任务容器拉取策略: always, if-not-present, never + fetch_timeout: 5s + fetch_interval: 2s + # Runner 标签 + labels: + - "ubuntu-latest:host" + - "self-hosted:host" + +container: + # 容器网络模式 + network: "host" + # 是否启用特权模式 + privileged: false + # 容器选项 + options: + # 工作目录父路径 + workdir_parent: + # 有效的卷挂载 + valid_volumes: + - /workspace/** + # Docker 主机 + docker_host: "" + # 强制拉取镜像 + force_pull: false + +host: + # 主机工作目录 + workdir_parent: