gitlink-cli/workflows/deploy.sh

246 lines
9.2 KiB
Bash

#!/usr/bin/env bash
# ================================================================
# GitLink Community Ops — 一键部署到 Linux 服务器
#
# 用法:
# 在本地执行 (scp 上传 + 远程安装):
# bash deploy.sh --host 1.2.3.4 --port 8080 \
# --secret "my-secret" --owner mengcheng --repo gitlink_help_center
#
# 或在服务器本地执行 (已经上传完文件后):
# sudo bash deploy.sh --local --port 8080 --secret "my-secret" \
# --owner mengcheng --repo gitlink_help_center --webhook-url "https://1.2.3.4:8080/webhook"
# ================================================================
set -euo pipefail
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
log() { echo -e "${CYAN}[INFO]${NC} $*"; }
ok() { echo -e "${GREEN}[ OK]${NC} $*"; }
err() { echo -e "${RED}[ ERR]${NC} $*"; exit 1; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
# ── 参数 ────────────────────────────────────────────────────────
HOST=""
PORT="8080"
SECRET=""
OWNER=""
REPO=""
WEBHOOK_URL=""
LOCAL=false
INSTALL_DIR="/opt/gitlink-webhook"
SYSTEMD_USER="gitlink"
usage() {
echo "Usage: $0 --host IP --port PORT --secret SECRET --owner OWNER --repo REPO"
echo "$0 --local --port PORT --secret SECRET --owner OWNER --repo REPO --webhook-url URL"
echo ""
echo " 远程部署 (本地执行):"
echo " --host IP 服务器公网 IP"
echo " --port PORT 监听端口 (默认 8080)"
echo " --secret SECRET HMAC 密钥"
echo " --owner OWNER GitLink 仓库所有者"
echo " --repo REPO GitLink 仓库名"
echo ""
echo " 本地安装 (服务器上执行):"
echo " --local 在当前机器安装"
echo " --webhook-url URL 完整 webhook 回调 URL"
exit 1
}
while [[ $# -gt 0 ]]; do
case "$1" in
--host) HOST="$2"; shift 2 ;;
--port) PORT="$2"; shift 2 ;;
--secret) SECRET="$2"; shift 2 ;;
--owner) OWNER="$2"; shift 2 ;;
--repo) REPO="$2"; shift 2 ;;
--webhook-url) WEBHOOK_URL="$2"; shift 2 ;;
--local) LOCAL=true; shift ;;
--help|-h) usage ;;
*) err "Unknown arg: $1" ;;
esac
done
# ── 校验 ────────────────────────────────────────────────────────
if [[ "$LOCAL" == "true" ]]; then
[[ -z "$WEBHOOK_URL" ]] && err "--webhook-url is required in --local mode"
[[ -z "$SECRET" ]] && err "--secret is required"
else
[[ -z "$HOST" ]] && err "--host is required for remote deployment"
[[ -z "$SECRET" ]] && err "--secret is required"
WEBHOOK_URL="https://${HOST}:${PORT}/webhook"
fi
WORKFLOW_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REQUIRED_FILES=(
"01a-webhook-listener.py"
"01a-issue-triage.sh"
"01a-webhook-setup.sh"
"01-community-ops.sh"
"lib/common.sh"
"gitlink-webhook.service"
)
# ── 远程部署 ─────────────────────────────────────────────────────
if [[ "$LOCAL" != "true" ]]; then
log "Deploying to $HOST ..."
# 检查文件
for f in "${REQUIRED_FILES[@]}"; do
[[ -f "$WORKFLOW_DIR/$f" ]] || err "Missing: $WORKFLOW_DIR/$f"
done
log "Uploading files to $HOST:$INSTALL_DIR ..."
ssh "root@$HOST" "mkdir -p $INSTALL_DIR/webhook-logs $INSTALL_DIR/workflows/lib" || err "SSH connection failed"
scp "$WORKFLOW_DIR/01a-webhook-listener.py" "root@$HOST:$INSTALL_DIR/"
scp "$WORKFLOW_DIR/01a-issue-triage.sh" "root@$HOST:$INSTALL_DIR/workflows/"
scp "$WORKFLOW_DIR/01-community-ops.sh" "root@$HOST:$INSTALL_DIR/workflows/"
scp "$WORKFLOW_DIR/01a-webhook-setup.sh" "root@$HOST:$INSTALL_DIR/workflows/"
scp "$WORKFLOW_DIR/lib/common.sh" "root@$HOST:$INSTALL_DIR/workflows/lib/"
scp "$WORKFLOW_DIR/gitlink-webhook.service" "root@$HOST:$INSTALL_DIR/"
ok "Files uploaded"
log "Running remote installation..."
ssh "root@$HOST" "bash -s" << REMOTE_SCRIPT
set -e
INSTALL_DIR="$INSTALL_DIR"
PORT="$PORT"
SECRET="$SECRET"
OWNER="$OWNER"
REPO="$REPO"
WEBHOOK_URL="$WEBHOOK_URL"
SYSTEMD_USER="$SYSTEMD_USER"
echo '=== Installing GitLink Webhook ==='
# 1. 创建用户
if ! id -u \$SYSTEMD_USER &>/dev/null; then
useradd -r -s /usr/sbin/nologin -d \$INSTALL_DIR \$SYSTEMD_USER
echo "[OK] User \$SYSTEMD_USER created"
else
echo "[OK] User \$SYSTEMD_USER exists"
fi
# 2. 设置权限
chown -R \$SYSTEMD_USER:\$SYSTEMD_USER \$INSTALL_DIR
chmod +x \$INSTALL_DIR/01a-webhook-listener.py
chmod +x \$INSTALL_DIR/workflows/*.sh
echo "[OK] Permissions set"
# 3. 创建 .env
cat > \$INSTALL_DIR/.env << EOF
WEBHOOK_PORT=$PORT
WEBHOOK_SECRET=$SECRET
EOF
chmod 600 \$INSTALL_DIR/.env
chown \$SYSTEMD_USER:\$SYSTEMD_USER \$INSTALL_DIR/.env
echo "[OK] .env created"
# 4. 开放防火墙
if command -v ufw &>/dev/null && ufw status | grep -q "Status: active"; then
ufw allow \$PORT/tcp 2>/dev/null || true
echo "[OK] Firewall: port \$PORT opened"
elif command -v firewall-cmd &>/dev/null; then
firewall-cmd --permanent --add-port=\$PORT/tcp 2>/dev/null || true
firewall-cmd --reload 2>/dev/null || true
echo "[OK] Firewall: port \$PORT opened"
else
echo "[WARN] No firewall detected — ensure port \$PORT is open in security group"
fi
# 5. 安装 systemd 服务
cp \$INSTALL_DIR/gitlink-webhook.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable gitlink-webhook
systemctl restart gitlink-webhook
echo "[OK] Systemd service installed and started"
# 6. 等待启动
sleep 2
systemctl status gitlink-webhook --no-pager | head -5
echo ''
echo '=== Installation complete ==='
echo "Health check: http://$HOST:$PORT/"
echo "Webhook URL: $WEBHOOK_URL"
REMOTE_SCRIPT
ok "Remote installation complete"
# 7. 注册 webhook
echo ""
log "Registering webhook on GitLink..."
ssh "root@$HOST" "cd \$INSTALL_DIR/workflows && bash 01a-webhook-setup.sh --webhook-url '$WEBHOOK_URL' --owner '$OWNER' --repo '$REPO' --secret '$SECRET'" || {
warn "Webhook registration failed — you can run manually:"
echo " ssh root@$HOST"
echo " cd $INSTALL_DIR/workflows"
echo " bash 01a-webhook-setup.sh --webhook-url '$WEBHOOK_URL' --owner '$OWNER' --repo '$REPO' --secret '$SECRET'"
}
echo ""
echo -e "${GREEN}╔══════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║ Deployment Complete! ║${NC}"
echo -e "${GREEN}║ ║${NC}"
echo -e "${GREEN}║ Health: http://$HOST:$PORT/ ║${NC}"
echo -e "${GREEN}║ Webhook: $WEBHOOK_URL${NC}"
echo -e "${GREEN}║ Logs: ssh root@$HOST journalctl -u gitlink-webhook -f ║${NC}"
echo -e "${GREEN}╚══════════════════════════════════════════════════════════╝${NC}"
# ── 本地安装(在服务器上执行)─────────────────────────────────────
else
[[ "$EUID" -ne 0 ]] && err "Please run as root (sudo)"
log "Installing locally to $INSTALL_DIR ..."
# 创建用户
if ! id -u "$SYSTEMD_USER" &>/dev/null; then
useradd -r -s /usr/sbin/nologin -d "$INSTALL_DIR" "$SYSTEMD_USER"
ok "User $SYSTEMD_USER created"
fi
# 设置权限
chown -R "$SYSTEMD_USER:$SYSTEMD_USER" "$INSTALL_DIR"
chmod +x "$INSTALL_DIR/01a-webhook-listener.py"
chmod +x "$INSTALL_DIR/workflows/"*.sh 2>/dev/null || true
ok "Permissions set"
# .env
cat > "$INSTALL_DIR/.env" << EOF
WEBHOOK_PORT=$PORT
WEBHOOK_SECRET=$SECRET
EOF
chmod 600 "$INSTALL_DIR/.env"
chown "$SYSTEMD_USER:$SYSTEMD_USER" "$INSTALL_DIR/.env"
ok ".env created"
# 防火墙
if command -v ufw &>/dev/null && ufw status 2>/dev/null | grep -q "Status: active"; then
ufw allow "$PORT/tcp" 2>/dev/null || true
ok "UFW: port $PORT opened"
fi
# systemd
cp "$INSTALL_DIR/gitlink-webhook.service" /etc/systemd/system/
systemctl daemon-reload
systemctl enable gitlink-webhook
systemctl restart gitlink-webhook
ok "Systemd service installed"
sleep 2
systemctl status gitlink-webhook --no-pager | head -8
echo ""
echo -e "${GREEN}Local installation complete!${NC}"
echo " Health check: curl http://localhost:$PORT/"
echo " Status: systemctl status gitlink-webhook"
echo " Logs: journalctl -u gitlink-webhook -f"
echo ""
echo " Next: register webhook on GitLink:"
echo " bash $INSTALL_DIR/workflows/01a-webhook-setup.sh \\"
echo " --webhook-url '$WEBHOOK_URL' \\"
echo " --owner '$OWNER' --repo '$REPO' --secret '$SECRET'"
fi