Files
NeoBot/.github/workflows/main.yml
2026-01-23 01:25:52 +08:00

308 lines
12 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: 部署到生产环境
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:
inputs:
reason:
description: '手动触发部署的原因'
required: false
default: '手动部署'
jobs:
deploy:
runs-on: ubuntu-latest
environment: SSH-KEY
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
# ========== 新增:检出代码失败时的错误处理 ==========
- name: 处理代码检出失败
if: failure()
run: |
echo "❌ 代码检出失败!请检查仓库权限或网络问题"
exit 1
# ========== 新增配置清华源更新pip并安装项目依赖 ==========
- name: 配置清华源更新pip并安装项目依赖
id: install_pip_deps
# 开启 errexit出错立即终止和 xtrace输出执行命令
run: |
set -euo pipefail
echo "=== 开始配置清华源并安装pip依赖 ==="
# 1. 安装Python和pip确保环境有pip
echo "📦 安装Python和pip..."
sudo apt-get update -y
sudo apt-get install -y python3 python3-pip python3-venv --no-install-recommends
# 2. 配置pip清华镜像源临时生效避免污染全局
echo "🔧 配置pip清华镜像源..."
pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip3 config set install.trusted-host pypi.tuna.tsinghua.edu.cn
# 3. 更新pip到最新版本
echo "⬆️ 更新pip到最新版本..."
# 重试机制失败后重试2次每次间隔3秒
for i in {1..3}; do
if pip3 install --upgrade pip; then
break
elif [ $i -eq 3 ]; then
echo "❌ pip更新失败已重试3次"
exit 1
fi
echo "⚠️ pip更新失败3秒后重试第$i次..."
sleep 3
done
# 4. 检查项目依赖文件并安装
REQUIREMENTS_FILE="requirements.txt" # 可根据实际文件名修改如requirements/prod.txt
if [ -f "$REQUIREMENTS_FILE" ]; then
echo "📄 找到依赖文件 $REQUIREMENTS_FILE开始安装依赖..."
# 安装依赖并输出详细日志,失败时保留缓存便于排查
pip3 install --no-cache-dir -r "$REQUIREMENTS_FILE" 2>&1 | tee pip_install.log
echo "✅ pip依赖安装完成"
else
echo "⚠️ 未找到依赖文件 $REQUIREMENTS_FILE跳过依赖安装"
fi
# 5. 验证pip和依赖安装结果
echo "✅ pip版本$(pip3 --version)"
echo "✅ 已安装的依赖列表:"
pip3 list
# 依赖安装失败时的详细提示
continue-on-error: false
# ========== 原有步骤:安装系统依赖工具(强化错误处理) ==========
- name: 安装依赖工具
id: install_sys_deps
run: |
set -euo pipefail
echo "=== 开始安装系统依赖工具 ==="
# 配置清华源加速apt更新可选提升安装速度
sudo sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
sudo apt-get update -y || { echo "❌ apt更新失败"; exit 1; }
# 安装工具并验证
TOOLS="sshpass expect openssh-client"
for TOOL in $TOOLS; do
echo "📦 安装 $TOOL..."
if sudo apt-get install -y --no-install-recommends $TOOL; then
echo "✅ $TOOL 安装成功"
else
echo "❌ $TOOL 安装失败"
exit 1
fi
done
# 验证工具可用性
sshpass -V >/dev/null || { echo "❌ sshpass安装后不可用"; exit 1; }
expect -v >/dev/null || { echo "❌ expect安装后不可用"; exit 1; }
continue-on-error: false
# ========== 原有步骤配置SSH密钥强化错误处理 ==========
- name: 配置SSH密钥并启动ssh-agent
id: config_ssh
run: |
set -euo pipefail
echo "=== 开始配置SSH密钥 ==="
# 创建SSH目录并严格控制权限
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 处理私钥换行符问题,验证私钥完整性
echo "${{ secrets.KEY }}" | tr -d '\r' > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
# 验证私钥格式
if ! head -n 1 ~/.ssh/id_rsa | grep -q "BEGIN"; then
echo "❌ 私钥文件格式错误未找到BEGIN标记"
exit 1
fi
if ! tail -n 1 ~/.ssh/id_rsa | grep -q "END"; then
echo "❌ 私钥文件格式错误未找到END标记"
exit 1
fi
# 启动ssh-agent并加载私钥
eval $(ssh-agent -s)
export SSH_AGENT_PID SSH_AUTH_SOCK
echo "🔑 加载SSH私钥..."
expect -c "
set timeout 15
spawn ssh-add ~/.ssh/id_rsa
expect {
\"Enter passphrase for /home/runner/.ssh/id_rsa:\" {
send \"${{ secrets.PASSPHRASE }}\r\"
exp_continue
}
\"Identity added: /home/runner/.ssh/id_rsa\" {
puts \"✅ 私钥加载成功\"
exit 0
}
\"Bad passphrase, try again\" {
puts \"❌ 私钥密码错误PASSPHRASE\"
exit 1
}
timeout {
puts \"❌ 私钥加载超时\"
exit 1
}
eof {
puts \"❌ 私钥加载失败\"
exit 1
}
}
" || { echo "❌ 私钥加载失败,终止流程"; exit 1; }
# 配置SSH免主机检查
cat > ~/.ssh/config << EOF
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
GlobalKnownHostsFile /dev/null
ConnectTimeout 30
EOF
chmod 600 ~/.ssh/config
echo "✅ SSH密钥配置完成"
continue-on-error: false
# ========== 原有步骤:执行部署(强化错误处理) ==========
- name: 执行部署
id: run_deploy
run: |
set -euo pipefail
echo "=== 开始执行服务器部署 ==="
# 定义部署命令(抽离便于维护)
DEPLOY_CMD=$(cat << 'EOF'
set -exuo pipefail
echo "=== 服务器部署开始($(date)==="
# 服务器端也配置清华源可选如需在服务器安装pip依赖
pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple || true
# 测试sudo权限
echo "${SERVER_PASSWORD}" | sudo -S -k -p '' whoami || { echo "❌ sudo权限验证失败"; exit 1; }
# 停止服务(失败不终止,避免服务未启动导致部署中断)
echo "🛑 停止neobot服务..."
echo "${SERVER_PASSWORD}" | sudo -S -k -p '' systemctl stop neobot.service || true
sleep 2
# 修复文件权限
echo "🔧 修复文件权限..."
echo "${SERVER_PASSWORD}" | sudo -S -k -p '' chown -R "${SERVER_USER}":"${SERVER_USER}" /home/luoxiaolei/neobot/NeoBot || { echo "❌ 文件权限修复失败"; exit 1; }
# 拉取代码
cd /home/luoxiaolei/neobot/NeoBot || { echo "❌ 项目目录不存在"; exit 1; }
echo "⬇️ 拉取最新代码..."
git pull origin main || { echo "❌ 代码拉取失败"; exit 1; }
# 使用pip3.14升级依赖
echo "📦 使用pip3.14升级项目依赖..."
if [ -f "requirements.txt" ]; then
echo "📄 发现requirements.txt使用pip3.14安装/升级依赖..."
# 尝试使用pip3.14如果不存在则使用pip3
if command -v pip3.14 &> /dev/null; then
pip3.14 install --upgrade -r requirements.txt || { echo "❌ pip3.14依赖安装失败"; exit 1; }
echo "✅ pip3.14依赖安装完成"
else
echo "⚠️ pip3.14未找到尝试使用pip3..."
pip3 install --upgrade -r requirements.txt || { echo "❌ pip3依赖安装失败"; exit 1; }
echo "✅ pip3依赖安装完成"
fi
else
echo "⚠️ 未找到requirements.txt文件跳过依赖安装"
fi
# 启动服务
echo "🚀 启动neobot服务..."
echo "${SERVER_PASSWORD}" | sudo -S -k -p '' systemctl start neobot.service || { echo "❌ 服务启动失败"; exit 1; }
sleep 3
# 检查服务状态
echo "📋 检查服务状态..."
if ! echo "${SERVER_PASSWORD}" | sudo -S -k -p '' systemctl status neobot.service --no-pager --full; then
echo "❌ neobot服务启动异常查看日志"
echo "${SERVER_PASSWORD}" | sudo -S -k -p '' journalctl -u neobot.service --no-pager -n 50
exit 1
fi
echo "✅ 服务器部署完成($(date)==="
EOF
)
# 替换变量并执行部署
export SERVER_PASSWORD="${{ secrets.SERVER_PASSWORD }}"
export SERVER_USER="${{ secrets.SERVER_USER }}"
DEPLOY_CMD=$(echo "$DEPLOY_CMD" | sed "s/\${SERVER_PASSWORD}/${{ secrets.SERVER_PASSWORD }}/g")
DEPLOY_CMD=$(echo "$DEPLOY_CMD" | sed "s/\${SERVER_USER}/${{ secrets.SERVER_USER }}/g")
# 执行部署带SSH调试日志
if ! sshpass -p "${{ secrets.SERVER_PASSWORD }}" ssh -v \
-o IdentityFile=~/.ssh/id_rsa \
-o ConnectTimeout=30 \
-p 42422 ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_ADDRESS }} "$DEPLOY_CMD"; then
echo "❌ 部署命令执行失败"
exit 1
fi
echo "✅ 部署流程全部完成"
continue-on-error: false
# ========== 强化错误处理:步骤失败后的详细提示 ==========
- name: 部署失败详细排查
if: failure()
run: |
echo "=================================================="
echo "❌ 部署失败!详细排查信息:"
echo "=================================================="
# 输出各步骤状态
echo "🔍 步骤状态:"
echo " - 代码检出:${{ steps.install_pip_deps.outcome }}"
echo " - pip依赖安装${{ steps.install_pip_deps.outcome }}"
echo " - 系统依赖安装:${{ steps.install_sys_deps.outcome }}"
echo " - SSH配置${{ steps.config_ssh.outcome }}"
echo " - 部署执行:${{ steps.run_deploy.outcome }}"
# 按失败步骤给出排查建议
if [ "${{ steps.install_pip_deps.outcome }}" = "failure" ]; then
echo "📌 排查重点pip依赖安装失败"
echo " 1. 检查requirements.txt文件格式是否正确"
echo " 2. 检查清华源是否可访问curl https://pypi.tuna.tsinghua.edu.cn/simple"
echo " 3. 检查依赖包名称/版本是否存在错误"
fi
if [ "${{ steps.config_ssh.outcome }}" = "failure" ]; then
echo "📌 排查重点SSH配置失败"
echo " 1. 检查KEY私钥是否完整包含BEGIN/END标记"
echo " 2. 检查PASSPHRASE私钥密码是否正确"
echo " 3. 检查服务器公钥是否已添加到authorized_keys"
fi
if [ "${{ steps.run_deploy.outcome }}" = "failure" ]; then
echo "📌 排查重点(部署执行失败):"
echo " 1. 检查SERVER_PASSWORD服务器密码是否正确"
echo " 2. 检查服务器42422端口是否开放"
echo " 3. 检查服务器项目目录是否存在:/home/luoxiaolei/neobot/NeoBot"
echo " 4. 查看服务器日志journalctl -u neobot.service -n 50"
fi
exit 1
# ========== 部署成功提示 ==========
- name: 部署成功提示
if: success()
run: |
echo "✅ 部署成功!"
echo "📝 部署信息:"
echo " - 触发方式:${{ github.event_name }}"
echo " - 分支:${{ github.ref_name }}"
echo " - 提交ID${{ github.sha }}"
echo " - 手动触发原因:${{ github.event.inputs.reason || '自动触发' }}"