背景
因为我们的electron程序已经开发完成,期望要能开发人员每次上传代码,打了tag就自动build一份deb文件,自动上传到minio,方便运维人员去拿deb文件部署到ubuntu环境上。我们已有的技术栈包含droneCI,minio,python,于是边有了该方案。本文省略了vault,ldap,minio,harbor的安装与配置,这些程序的安装配置在本网站的其他文章里,就不一一贴出来了
架构图
解释:
1.前端开发上传electron代码到git服务端
2.git服务端通过webhook方式通知drone-server产生了。例如本文只测试的是发布tag触发webhook,还有很多种触发方式都可以设置
3.drone-server收到通知后,再在drone-runner所在的k8s集群里启动一个包含nodejs和python的任务容器
4.任务容器通过electron-forge make 命令打包一个deb文件
5.任务容器通过minio提供的python sdk上传deb文件到minio
drone插件编写
要完成上述目标,第一步就是得编写一个drone的插件
我编写该插件使用的是nodejs16版本的debian系统,然后通过提前安装好需要的如下表格里的工具。注意,因为我用的是华为源,2021年12月9日的时候,华为镜像上最新的electron只到16.0.2版本,所以注意指定版本号
介绍:该插件使用nodejs16版本的debian系统,然后通过提前安装好需要的如下工具。注意,因为我用的是华为源,2021年12月9日的时候,华为镜像上最新的electron只到16.0.2版本,所以注意指定版本号
工具名 |
rpm |
python3-pip |
python3 |
fakeroot |
electron@v16.0.2 |
electron-prebuilt-compile |
electron-forge |
dpkg |
minio的python sdk |
代码有3个文件main.py Dockerfile ,requirements.txt,下面是详细介绍
main.py
代码功能是先获取环境变量,然后使用git的tag号替换掉package.json里的version字段。执行yarn install,yanr make,通过环境变量找到需要上传的文件,通过pythonde的sdk上传到minio里。详细代码如下
#main.py import json import os import subprocess from minio import Minio from minio.error import S3Error endpoint = "minio.sfere.local" access_key = "bababa" secret_key = "bababa" bucket = "electronjs" folder_path = "/drone/src/out/make/deb/x64" suffix = "deb" tag = "0.0.0" def find_file_by_suffix(target_dir, target_suffix="deb"): find_res = [] target_suffix_dot = "." + target_suffix walk_generator = os.walk(target_dir) for root_path, dirs, files in walk_generator: if len(files) < 1: continue for file in files: file_name, suffix_name = os.path.splitext(file) if suffix_name == target_suffix_dot: find_res.append(os.path.join(root_path, file)) return find_res def get_environment(): global endpoint, access_key, secret_key, bucket, suffix, tag if "PLUGIN_ENDPOINT" in os.environ: endpoint = os.environ["PLUGIN_ENDPOINT"] if "PLUGIN_ACCESS_KEY" in os.environ: access_key = os.environ["PLUGIN_ACCESS_KEY"] if "PLUGIN_SECRET_KEY" in os.environ: secret_key = os.environ["PLUGIN_SECRET_KEY"] if "PLUGIN_BUCKET" in os.environ: bucket = os.environ["PLUGIN_BUCKET"] if "PLUGIN_SUFFIX" in os.environ: suffix = os.environ["PLUGIN_SUFFIX"] if "PLUGIN_TAG" in os.environ: tag = os.environ["PLUGIN_TAG"] def yarn_make(): with open('./package.json', 'r', encoding='utf8')as fp: json_data = json.load(fp) json_data['version'] = tag with open('./package.json', 'w', encoding='utf8')as fp: json.dump(json_data, fp, ensure_ascii=False, indent=2) print('package version replace to ' + tag) print(subprocess.run("yarn install", shell=True)) print(subprocess.run("yarn make", shell=True)) def upload_file(): file_list = find_file_by_suffix(folder_path, suffix) # 创建minio连接,这里因为我们是http的,所以secure=False client = Minio( endpoint=endpoint, access_key=access_key, secure=False, secret_key=secret_key, ) # 检查bucket是否存在,不存在就创建bucket found = client.bucket_exists(bucket) if not found: client.make_bucket(bucket) else: print("Bucket 'electronjs' already exists") # 上传文件到bucket里 for file in file_list: name = os.path.basename(file) client.fput_object( bucket, name, file, ) print( "'" + file + "' is successfully uploaded as " "object '" + name + "' to bucket '" + bucket + "'." ) if __name__ == "__main__": get_environment() yarn_make() try: upload_file() except S3Error as exc: print("error occurred.", exc)
Dockerfile
取一个node16版本的debian系统,使用国内源安装我们在之前列出来要用的工具,然后指定程序入口是我们的python程序。编写完后,使用docker build -t drone-electron-minio-plugin:0.1.0 . 做一个镜像上传到私仓里
FROM node:16-buster RUN npm config set registry https://mirrors.huaweicloud.com/repository/npm/ \ && npm config set disturl https://mirrors.huaweicloud.com/nodejs \ && npm config set sass_binary_site https://mirrors.huaweicloud.com/node-sass \ && npm config set phantomjs_cdnurl https://mirrors.huaweicloud.com/phantomjs \ && npm config set chromedriver_cdnurl https://mirrors.huaweicloud.com/chromedriver \ && npm config set operadriver_cdnurl https://mirrors.huaweicloud.com/operadriver \ && npm config set electron_mirror https://mirrors.huaweicloud.com/electron/ \ && npm config set python_mirror https://mirrors.huaweicloud.com/python \ && npm config set canvas_binary_host_mirror https://npm.taobao.org/mirrors/node-canvas-prebuilt/ \ && npm install -g npm@8.2.0 \ && yarn config set registry https://mirrors.huaweicloud.com/repository/npm/ \ && yarn config set disturl https://mirrors.huaweicloud.com/nodejs \ && yarn config set sass_binary_site https://mirrors.huaweicloud.com/node-sass \ && yarn config set phantomjs_cdnurl https://mirrors.huaweicloud.com/phantomjs \ && yarn config set chromedriver_cdnurl https://mirrors.huaweicloud.com/chromedriver \ && yarn config set operadriver_cdnurl https://mirrors.huaweicloud.com/operadriver \ && yarn config set electron_mirror https://mirrors.huaweicloud.com/electron/ \ && yarn config set python_mirror https://mirrors.huaweicloud.com/python \ && yarn config set canvas_binary_host_mirror https://npm.taobao.org/mirrors/node-canvas-prebuilt/ \ && yarn global add electron@v16.0.2 electron-forge electron-prebuilt-compile\ && sed -i "s@http://ftp.debian.org@https://repo.huaweicloud.com@g" /etc/apt/sources.list \ && sed -i "s@http://security.debian.org@https://repo.huaweicloud.com@g" /etc/apt/sources.list \ && sed -i "s@http://deb.debian.org@https://repo.huaweicloud.com@g" /etc/apt/sources.list \ && apt update \ && apt install -y fakeroot dpkg rpm python3 python3-pip ADD . . WORKDIR . RUN pip3 install -r ./requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple #CMD ["python3","/main.py"] WORKDIR /drone/src ENTRYPOINT ["python3", "/main.py"]
requirements.txt
minio==7.1.2
electron仓库代码
我们的electron仓库里要添加一个.drone.yml文件和对package.json稍微进行一些修改
package.json
.drone.yml
droneCI的流水线文件,使用了我们在上一节里build出来的drone插件镜像
流水线演示
需要人手动操作的
流水线自动操作的