Jenkins Pipeline 构建复杂的Electron程序
最近一年都在搗騰Electron,從0.X版本,到現在最新Stable的3.X版本。一路上踩的坑很多,Electron的版本號也飛快的。項目設立的初衷是一份代碼,即可構建出Windows和Mac,并且部分功能模塊可以與Web版公用,因此我們項目名為:三體。
由于程序比較復雜,使用Electron程度也較深,因此對比一般的桌面程序,構建流程比較繁瑣,因此項目開始之初,就使用Jenkins作為我們項目的自動構建的工具。隨著時間的推移,Jenkins的構建任務也一步步的智能化,力求智能,省心,省力。
Jenkins的安裝和部署這些就不多說了,讀者自行了解。
Jenkins單獨部署
項目開始之初,采用的Jenkins的方式就是:windows構建主機安裝一個Jenkins,Mac主機安裝一個Jenkins。當需要構建時候,手動點下運行任務。
這估計也是最多人使用Jenkins的方式,0門檻的入門。
優點:部署簡單,入門快 弱點:每次執行任務,需要訪問兩個Jenkins(這個時候,我們就只有兩個主機構建,如果多個主機,則需要訪問多個Jenkins),然后再執行任務。
Jenkins多節點部署
到了某個時候,發現實在太麻煩了,就使用單個Jenkins,然后通過節點管理執行Jenkins任務。
由于我們桌面端程序,構建過程,還需要把其他團隊的項目進行構建,放入到我們程序的指定目錄(JsBundle),這時候Jenkins的Config Files就大顯身手,把構建其他JsBundle的命令放入Config Files(如果包沒變更,則跳過構建,獲取緩存的包),這樣就沒必要每個構建任務重復錄入相同的流程,如圖feature, master等。
這時候幸福滿滿的,所有任務都可以通過Jenkins執行了,而且構建權限開放給所有開發,隨時構建包。
優點:充分利用不同機器資源,組建為構建集群。
Jenkins多配置
如上圖所示,我們有很多構建任務,有C++的,有第三方Node(預構建為二進制包,例如Napajs),但是核心構建我們的安裝包也有不同的任務,例如開發構建的是feature,測試構建的是master,灰度和發布則還有其他。但其實他們的構建流程都幾乎一致的。
上述的Jenkins使用方式,大概持續了大半年多,一直也挺滿意,覺得挺美好的。這時候,公司大力發展混合云,桌面端程序也需要按企業資源構建(簡單理解,就是類似手機的各種渠道包吧)
但是混合云的構建,由別的團隊負責,因此搭了另外一套Jenkins,我們團隊提供構建步驟,并且額外還有替換企業資源包的步驟。好景不長,這樣的方式,進行了一兩個月,問題逐漸暴露出來,每當我們需要修改構建步驟,都需要通知其他團隊一并進行修改。
因此思考,有沒方式可以改善這種方式呢?恰逢把Jenkins升級了一番,發現以下這
根據描述,好像可以解決我們一些問題,例如上面圖里面的全平臺構建,不需要再搞兩個任務了,起碼能干掉一半的任務,每次修改腳本,可以省掉一半修改量了。
但是還是沒根本解決問題,只是優化了一點。這時候,發現了Jenkins Pipeline,趕緊了解一下,眼前一亮,好像很美好。
Jenkins Pipeline
趕緊嘗試一下,由于我們項目過于復雜,沒辦法很省心省力的用起來。試了幾回,都打算放棄了幾回,只是不甘心,還是念念不忘。真正的從入門到“放棄”。
由于Jenkins Pipeline對于大部分人來說,過于高深,因此一直擔心腳本太復雜,對其他維護的同事來說是個負擔。(作為Lead,還是得考慮維護成本的,否則自個Hight不行),因此尋求簡單易懂,但又能組織形成復雜的構建步驟的平衡點。
Jenkins Pipeline的腳本形式分為:聲明式和腳本式,初次采用了聲明式,因此易懂,類似json的結構。但是嘗試了寫了下來,發現嵌套層數很多,有點累贅。最后還是采用了腳本式的,結合現學的groovy語法把一些復雜的邏輯,以前通過Config Files編寫的邏輯獨立為單獨的文件,保持主文件的清爽。
最結合之前的Multi-configuration,完美...
廢話不說,直接上腳本代碼
properties([parameters([string(name: 'runNode', defaultValue: 'mac', description: '節點'),string(name: 'cloudhubX_branch', defaultValue: 'master', description: '三體分支'),string(name: 'xx_branch', defaultValue: 'release', description: 'XX分支'), ])])node ("${params.runNode}") {checkout scm;def noCacheToBuild = load("${WORKSPACE}/.jenkins/noCacheToBuild.groovy")def check = load("${WORKSPACE}/.jenkins/check.groovy")stage('pre') {// 檢查任務check()sh 'rm -rf node_modules build dist bundle'}ansiColor('xterm') {stage('XX') {dir(".resource/xx") {def git = git(branch: env.xx_branch,credentialsId: 'git_ssh', changelog:true, url: '.............')noCacheToBuild(git, 'JsBundle的目錄名', 'dist') { // 如果緩存找不到,則構建,否則返回緩存sh """yarn installyarn run build"""}}}// .............stage('cloudhub') {sh """yarn installyarn buildyarn run publish $OS"""// 推送到nginxsshPublisher(publishers: [sshPublisherDesc(configName: 'master', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: "/$cloudhubx_branch/${OS}", remoteDirectorySDF: false, removePrefix: 'install', sourceFiles: 'install/*.*')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])}} }復制代碼發展到這,項目都可以復用一個構建任務,如下圖,由上游項目傳不同的參數觸發
下一步計劃
這次的調整,可以把公有云的產品構建都統一為一個了。把Jenkinsfile放入到工程,以后修改都可以直接修改,不用擔心構建任務與項目代碼不匹配了。
- 干掉混合云的Jenkins,都收攏在一個構建平臺
- 嘗試把構建任務不同stage,由不同機器執行。例如:C++的由指定平臺的編譯機器,JsBundle由服務器Docker構建,Electron本身由另外的機器打包
總結
以上是生活随笔為你收集整理的Jenkins Pipeline 构建复杂的Electron程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP解决网站大流量与高并发
- 下一篇: Go语言(Golang)约瑟夫游戏(Jo