electron+droneCI+minio流水线
背景
因为我们的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插件镜像