背景
因為我們的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 |
[email protected] |
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 [email protected] \
&& 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 [email protected] 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插件鏡像