logoSpectreAlan's blogs
python实现前端项目自动化打包部署
标签:
Python
Linux
服务器
类别:运维
创建时间: 2019-08-18 22:27:18
字数总计: 5.03 k
建议阅读时长: 6 分钟
阅读量: 360

使用方法

  • 本地安装python环境,并且配置好环境变量,不会的点我
  • 在本地新建auto.py然后粘贴进以下脚本,然后修改顶部注释部分的相关参数
  • 打开命令行工具,cd到auto.py所在目录,然后python auto.py回车执行脚本
  • 按照提示输入服务器登录密码,回车

配置

1import paramiko 2import os 3 4# —————————————————————此处配置打包相关参数——————————————————————— 5# 本地项目目录 6project_path = r'E:\projects\cloud-music' 7# 项目打包后的目录,一般为dist或者build 8build_path = 'build' 9# 服务器目录 10remote_path = r'/www/cloud-music' 11# 服务器地址 12hostname = '192.168.1.225' 13# 登陆服务器的用户名 14username = 'fuck' 15# ————————————————————————配置结束————————————————————————————— 16 17 18class SSHConnect: 19 # 定义一个私有变量,用来保存ssh连接通道,初始化为None 20 __transport = None 21 22 # 初始化构造函数(主机,用户名,密码,端口,默认22) 23 def __init__(self, hostname, username, password, port=22): 24 self.hostname = hostname 25 self.port = port 26 self.username = username 27 self.password = password 28 # 创建 ssh 连接通道 29 self.connect() 30 31 # 建立ssh 连接通道,并绑定在 __transport 上 32 def connect(self): 33 try: 34 # 设置SSH 连接的远程主机地址和端口 35 self.__transport = paramiko.Transport((self.hostname, self.port)) 36 # 通过用户名和密码连接SSH服务端 37 self.__transport.connect(username=self.username, password=self.password) 38 except Exception as e: 39 # 连接出错 40 print(e) 41 42 # 执行linux命令 43 def exec(self, command): 44 45 # 创建 ssh 客户端 46 ssh = paramiko.SSHClient() 47 # 指定连接的通道 48 ssh._transport = self.__transport 49 50 # 打开一个Channel并执行命令, 调用 exec_command 方法执行命令 51 stdin, stdout, stderr = ssh.exec_command(command) 52 53 # 获取命令结果,返回是二进制,需要编码一下 54 res = stdout.read().decode('utf-8') 55 # 获取错误信息 56 error = stderr.read().decode('utf-8') 57 58 # 如果没出错 59 if error.strip(): 60 # 返回错误信息 61 return error 62 else: 63 # 返回结果 64 return res 65 66 # 前端打包(入参work_path为项目目录) 67 def build(self, work_path): 68 # 开始打包 69 print('_______________________________________________') 70 print('正在打包...') 71 # 打包命令 72 cmd = 'npm run build' 73 # 切换到需要项目目录 74 os.chdir(work_path) 75 # 当前项目目录下执行打包命令 76 if os.system(cmd) == 0: 77 # 打包完成 78 print('打包完成!') 79 print('开始上传文件...') 80 81 # 文件上传 82 def upload(self, local_path, target_path): 83 # 判断路径问题 84 if not os.path.exists(local_path): 85 return print('local path is not exist') 86 87 # 实例化一个 sftp 对象,指定连接的通道 88 sftp = paramiko.SFTPClient.from_transport(self.__transport) 89 # 打包后的文件路径 90 local_path = os.path.join(local_path, build_path) 91 # 本地路径转换,将windows下的 \ 转成 / 92 local_path = '/'.join(local_path.split('\\')) 93 94 # 递归上传文件 95 self.upload_file(sftp, local_path, target_path) 96 97 print('Everything is ok,Have a nice day!') 98 # 关闭连接 99 self.close() 100 101 # 递归上传文件 102 def upload_file(self, sftp, local_path, target_path): 103 # 判断当前路径是否是文件夹 104 if not os.path.isdir(local_path): 105 # 如果是文件,获取文件名 106 file_name = os.path.basename(local_path) 107 # 检查服务器文件夹是否存在 108 self.check_remote_dir(sftp, target_path) 109 # 服务器创建文件 110 target_file_path = os.path.join(target_path, file_name).replace('\\', '/') 111 # 上传到服务器 112 sftp.put(local_path, target_file_path) 113 else: 114 # 查看当前文件夹下的子文件 115 file_list = os.listdir(local_path) 116 # 遍历子文件 117 for p in file_list: 118 # 拼接当前文件路径 119 current_local_path = os.path.join(local_path, p).replace('\\', '/') 120 # 拼接服务器文件路径 121 current_target_path = os.path.join(target_path, p).replace('\\', '/') 122 # 如果已经是文件,服务器就不需要创建文件夹了 123 if os.path.isfile(current_local_path): 124 # 提取当前文件所在的文件夹 125 current_target_path = os.path.split(current_target_path)[0] 126 # 递归判断 127 self.upload_file(sftp, current_local_path, current_target_path) 128 129 # 创建服务器文件夹 130 def check_remote_dir(self, sftp, target_path): 131 try: 132 # 判断文件夹是否存在 133 sftp.stat(target_path) 134 except IOError: 135 # 创建文件夹 136 self.exec(r'mkdir -p %s ' % target_path) 137 138 # 自动化打包部署 139 def auto_deploy(self, local_path, target_path): 140 # 打包构建 141 self.build(local_path) 142 # 清空文件 143 self.clear_remote_dir(target_path) 144 # 文件上传 145 self.upload(local_path, target_path) 146 147 # 清空文件夹 148 def clear_remote_dir(self, target_path): 149 if target_path[-1] == '/': 150 cmd = f'rm -rf {target_path}*' 151 else: 152 cmd = f'rm -rf {target_path}/*' 153 self.exec(cmd) 154 155 # 关闭连接 156 def close(self): 157 self.__transport.close() 158 159 # 销毁实例 160 def __del__(self): 161 self.__transport.close() 162 163 164if __name__ == '__main__': 165 # 实例化 166 password = input("请输入服务器连接密码:") 167 ssh = SSHConnect(hostname=hostname, username=username, password=password) 168 # 自动打包部署 169 ssh.auto_deploy(project_path, remote_path) 170
吐槽一下
copyright