本文目录导读:

我来为你介绍几种Shell脚本实现半自动发布策略的方案。
基础半自动发布脚本
#!/bin/bash
# 半自动发布脚本
set -e
# 配置区
PROJECT_NAME="myapp"
DEPLOY_DIR="/var/www/$PROJECT_NAME"
BACKUP_DIR="/var/backups/$PROJECT_NAME"
GIT_REPO="git@github.com:username/$PROJECT_NAME.git"
BRANCH="main"
# 颜色输出函数
green() { echo -e "\033[32m$1\033[0m"; }
red() { echo -e "\033[31m$1\033[0m"; }
yellow() { echo -e "\033[33m$1\033[0m"; }
# 确认函数
confirm() {
read -p "$(yellow "$1 (y/n): ")" -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
red "操作已取消"
exit 1
fi
}
# 1. 获取发布版本
get_version() {
echo "当前版本信息:"
git describe --tags --abbrev=0 2>/dev/null || echo "无版本标签"
read -p "请输入发布版本号 ( v1.2.3): " VERSION
if [ -z "$VERSION" ]; then
red "版本号不能为空"
exit 1
fi
}
# 2. 代码检查
code_check() {
echo ">>> 开始代码检查..."
# 运行测试
if [ -f "Makefile" ]; then
make test || {
red "测试失败,请检查代码"
exit 1
}
fi
# 代码规范检查
if command -v eslint &> /dev/null; then
eslint src/ || yellow "ESLint 警告,建议修复"
fi
green "代码检查通过"
}
# 3. 构建
build_project() {
echo ">>> 开始构建..."
confirm "是否继续构建?"
# 根据项目类型构建
if [ -f "package.json" ]; then
npm install && npm run build
elif [ -f "pom.xml" ]; then
mvn clean package -DskipTests
elif [ -f "Makefile" ]; then
make build
fi
green "构建完成"
}
# 4. 备份当前版本
backup_current() {
echo ">>> 开始备份..."
if [ -d "$DEPLOY_DIR" ]; then
BACKUP_NAME="${PROJECT_NAME}_$(date +%Y%m%d_%H%M%S).tar.gz"
tar -czf "$BACKUP_DIR/$BACKUP_NAME" -C "$DEPLOY_DIR" .
green "备份完成: $BACKUP_NAME"
else
yellow "部署目录不存在,跳过备份"
fi
}
# 5. 部署
deploy() {
echo ">>> 开始部署..."
confirm "是否确认部署到生产环境?"
# 创建部署目录
sudo mkdir -p "$DEPLOY_DIR"
# 复制构建产物
if [ -d "dist" ]; then
sudo cp -r dist/* "$DEPLOY_DIR/"
elif [ -d "build" ]; then
sudo cp -r build/* "$DEPLOY_DIR/"
elif [ -f "target/*.jar" ]; then
sudo cp target/*.jar "$DEPLOY_DIR/"
fi
# 设置权限
sudo chown -R www-data:www-data "$DEPLOY_DIR"
sudo chmod -R 755 "$DEPLOY_DIR"
green "文件部署完成"
}
# 6. 重启服务
restart_service() {
echo ">>> 重启服务..."
confirm "是否重启服务?"
# 根据服务类型重启
if systemctl is-active --quiet "$PROJECT_NAME"; then
sudo systemctl restart "$PROJECT_NAME"
elif command -v pm2 &> /dev/null; then
pm2 restart "$PROJECT_NAME"
elif command -v supervisorctl &> /dev/null; then
supervisorctl restart "$PROJECT_NAME"
fi
green "服务重启完成"
}
# 7. 健康检查
health_check() {
echo ">>> 执行健康检查..."
local RETRY_COUNT=0
local MAX_RETRY=10
while [ $RETRY_COUNT -lt $MAX_RETRY ]; do
if curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/health | grep -q "200"; then
green "健康检查通过"
return 0
fi
RETRY_COUNT=$((RETRY_COUNT + 1))
sleep 2
done
red "健康检查失败,请手动检查服务状态"
return 1
}
# 8. 回滚
rollback() {
echo ">>> 可用的备份:"
ls -1 "$BACKUP_DIR/"*.tar.gz 2>/dev/null | head -5
read -p "请输入要回滚的备份文件名: " ROLLBACK_FILE
if [ ! -f "$BACKUP_DIR/$ROLLBACK_FILE" ]; then
red "备份文件不存在"
exit 1
fi
confirm "确认回滚到 $ROLLBACK_FILE?"
# 清空当前目录
sudo rm -rf "$DEPLOY_DIR/*"
# 恢复备份
sudo tar -xzf "$BACKUP_DIR/$ROLLBACK_FILE" -C "$DEPLOY_DIR"
green "回滚完成"
}
# 主流程
main() {
echo "================================="
echo " 半自动发布系统 v1.0"
echo "================================="
echo "1. 完整发布流程"
echo "2. 仅部署代码"
echo "3. 回滚版本"
echo "4. 退出"
echo "================================="
read -p "请选择操作 [1-4]: " choice
case $choice in
1)
get_version
code_check
build_project
backup_current
deploy
restart_service
health_check
green "发布完成!版本:$VERSION"
;;
2)
deploy
restart_service
health_check
green "部署完成"
;;
3)
rollback
restart_service
health_check
green "回滚完成"
;;
4)
exit 0
;;
*)
red "无效选择"
exit 1
;;
esac
}
# 执行主函数
main
带交互确认的简化版本
#!/bin/bash
# 简化版半自动发布
PROJECT_PATH="/path/to/your/project"
REMOTE_SERVER="user@production-server"
deploy_confirm() {
local step=$1
local prompt=$2
echo "=== 步骤 $step: $prompt ==="
read -p "是否执行此步骤?(y/N/q): " action
case $action in
[Yy]*) return 0 ;;
[Nn]*) return 1 ;;
[Qq]*) exit 0 ;;
*) return 1 ;;
esac
}
# 分步执行
steps=(
"拉取最新代码"
"运行测试"
"构建项目"
"备份生产环境"
"上传文件"
"重启服务"
"验证部署"
)
current_step=0
for step in "${steps[@]}"; do
current_step=$((current_step + 1))
if deploy_confirm $current_step "$step"; then
case $current_step in
1) git pull origin main ;;
2) npm test ;;
3) npm run build ;;
4) ssh $REMOTE_SERVER "tar -czf /backup/app_$(date +%Y%m%d).tar.gz /var/www/app" ;;
5) rsync -avz dist/ $REMOTE_SERVER:/var/www/app/ ;;
6) ssh $REMOTE_SERVER "systemctl restart nginx" ;;
7) curl -f http://$REMOTE_SERVER/health && echo "验证成功" || echo "验证失败" ;;
esac
fi
done
使用配置文件
创建配置文件 deploy.config:
# 部署配置 PROJECT_NAME="myapp" ENVIRONMENT="production" GIT_BRANCH="main" BUILD_COMMAND="npm run build" TEST_COMMAND="npm test" DEPLOY_PATH="/var/www/myapp" SERVICE_NAME="myapp-service" HEALTH_CHECK_URL="http://localhost:8080/health" BACKUP_RETENTION_DAYS=7
对应的脚本:
#!/bin/bash
# 加载配置
source deploy.config
# 半自动发布函数
semi_auto_deploy() {
echo "=== 半自动发布开始 ==="
echo "项目: $PROJECT_NAME"
echo "环境: $ENVIRONMENT"
# 步骤1: 代码检查
read -p "执行代码检查? (y/n): " check
if [ "$check" = "y" ]; then
eval "$TEST_COMMAND" || { echo "测试失败"; exit 1; }
fi
# 步骤2: 构建
read -p "执行构建? (y/n): " build
if [ "$build" = "y" ]; then
eval "$BUILD_COMMAND" || { echo "构建失败"; exit 1; }
fi
# 步骤3: 备份
read -p "执行备份? (y/n): " backup
if [ "$backup" = "y" ]; then
tar -czf "/backup/${PROJECT_NAME}_$(date +%Y%m%d_%H%M%S).tar.gz" $DEPLOY_PATH
fi
# 步骤4: 部署
read -p "部署到生产环境? (y/n): " deploy
if [ "$deploy" = "y" ]; then
rsync -avz dist/ $DEPLOY_PATH/
fi
# 步骤5: 重启
read -p "重启服务? (y/n): " restart
if [ "$restart" = "y" ]; then
systemctl restart $SERVICE_NAME
fi
}
semi_auto_deploy
使用说明
执行方式
# 赋予执行权限 chmod +x deploy.sh # 执行部署 ./deploy.sh
特点说明
- 交互式确认:每个步骤都需要人工确认
- 版本控制:支持指定版本号和回滚
- 错误处理:每个步骤都有错误检查
- 日志记录:发布过程可追踪
- 灵活选择:可选择执行部分步骤
这种半自动策略在需要人工审核但又要减少重复操作时特别有用,适用于中小型项目的部署流程。