笔记:记一次本地打包上传服务器自动化脚本

202 阅读2分钟

问题:无自动化部署工具,上线/回滚操作不规范,且上线从不打tag,无法快速回滚。

简单实现本地shell脚本快速部署/回滚功能(打tag并将文件上传服务器)。

安装 sshpass 命令行工具,允许你在不交互输入密码的情况下,通过 SSH 连接到远程主机并执行命令。

shell脚本publish.sh:

#!/bin/bash

# 回滚操作方法
function rollback() {
  optionsStr=$(git tag -l --sort=-taggerdate)
  options=(${optionsStr// / })
  length=${#options[@]}

  echo "length: $length"
  # 如果没有tag直接退出
  if [[ $length -eq 1 && "${options[0]}" == "" ]]
  then
    echo "没有tag节点"
    exit 1
  fi

  select opt in "${options[@]}"
  do
    echo "即将切换到 $opt 此tag节点";
    git checkout $opt;
    echo "已切换到 $opt tag节点";
    break
  done
}

# 打包方法
function buildProject() {
  # 从 data.json 文件中读取 JSON 数据,第一个管道将每行的逗号去掉;第二个管道去掉{和};第三个管道去掉所有双引号;第四个管道替换第一个: 为=号
  json=$(cat sshKey.json | sed -r 's/",/"/' | egrep -v '^[{}]' | sed 's/"//g' | sed 's/: /=/1')
  #声明变量
  declare $json

  # 判断打包环境
  if [[ "$envStr" == "生产环境" ]]
  then
    echo "打包生产环境"
    npm run build:prod
    echo "生产包打印完成!"

    sshpass -p $prod_pwd scp -v -r ./dist root@$prod_ip:/soft/web

    # 如果不是回滚操作,则删除tag,重新打tag
    if [[ $statusStr != "回滚操作" ]]
    then
      currentCommit=$(git log -1 --pretty=format:"%H")
      echo "当前commit: $currentCommit"

      logList=$(git log -1 --decorate=full)
      echo "$logList"

      if [[ "$logList" != *"tag: "* ]]
      then
        echo "当前tag为空"
      else
        currentTag=$(git describe $currentCommit --tags | head -n 1)
        echo "当前tag: $currentTag"
        echo "当前tag不为空,删除当前tag"
        git tag -d $currentTag
        git push origin :$currentTag
      fi
      # 获取时间字符串
      datetimeStr=$(date "+%Y%m%d%H%M%S");
      echo $datetimeStr
      # git 打标签
      git tag "online-$datetimeStr"
      git push origin "online-$datetimeStr"
    fi

  else
    echo "打包测试环境"
    npm run build:dev
    echo "测试包打印完成"
    
    sshpass -p $dev_pwd scp -v -r ./dist root@$dev_ip:/soft/web
  fi

}

# # 检查本地文件是否都已提交
function checkGitstatus() {

  gitStatus=$(git status)
  # 判断本地代码是否都已经提交
  if [[ "$gitStatus" != *"Your branch is up to date with"* ]]
  then
    echo "请push分支代码"
    exit 1
  elif [[ "$gitStatus" != *"nothing to commit, working tree clean"* ]]
  then
    echo "请先提交代码"
    exit 1
  else 
    echo "本地代码都已提交,执行打包操作"
  fi
}

# 选择部署环境和要进行的操作
function selectFun() {
  printf "\e[32m 请选择要部署的环境,输入前方的数字:\n"
  envOptions=("测试环境" "生产环境")
  select envStr in "${envOptions[@]}"
  do
    echo -e "\033[31m已选择:$envStr \033[0m"
    break;
  done

  printf "\e[32m 请选择要进行的操作,输入前方的数字:\n"
  statusOptions=("部署操作" "回滚操作")
  select statusStr in "${statusOptions[@]}"
  do
    echo -e "\033[31m已选择:$statusStr \033[0m"
    break;
  done

  # 确认选择的环境和操作
  printf "\e[32m 确认要在\e[31m$envStr 进行 $statusStr \e[32m,输入前方的数字:\n"
  comfirmOptions=("确认" "重新选择")
  select comfirmStr in "${comfirmOptions[@]}"
  do
    echo -e "\033[31m已选择:$comfirmStr \033[0m"
    break;
  done
  # 重新选择重新执行选择操作
  if [[ $comfirmStr == "重新选择" ]]
  then
    clear
    selectFun
  fi
}

# 开始执行脚本,环境和操作选择
selectFun
# 检查本地代码是否都已经提交
checkGitstatus
# 判断是否是回滚操作
if [[ $statusStr == "回滚操作" ]]
then
  echo "回滚操作"
  rollback
  buildProject
else
  echo "部署操作"
  buildProject
fi

echo "部署完成"

服务器对应IP和密码配置文件sshKey.json

{
  "dev_ip": "192.168.xxx.xxx",
  "dev_pwd": "xxxxxxx",
  "prod_ip": "192.168.xxx.xxx",
  "prod_pwd": "xxxxxxxxxx"
}

最终执行sh ./publish.sh即可执行会出现下面选项,选择对应的选项即可:

image.png

直接运行publish.sh也可以,可能会遇到如下提示无执行权限,需要给publish.sh添加执行权限(执行chmod +x publish.sh),详细可参考:zhuanlan.zhihu.com/p/641820534

image.png