本文目录导读:

我来为你介绍几种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
特点说明
- 交互式确认:每个步骤都需要人工确认
- 版本控制:支持指定版本号和回滚
- 错误处理:每个步骤都有错误检查
- 日志记录:发布过程可追踪
- 灵活选择:可选择执行部分步骤
这种半自动策略在需要人工审核但又要减少重复操作时特别有用,适用于中小型项目的部署流程。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播