利用 electron-builder 實現 electron app 的署名/打包/釋出以及自動更新

再見尼克發表於2018-01-15

筆者系 electron-builder 貢獻者之一(#12)

electron-builder 是什麼

官方解釋如下:

A complete solution to package and build a ready for distribution Electron app with “auto update” support out of the box

簡單來說,electron-builder 就是一個可以將 electron app 打包成安裝器 (installer),以及可以為 electron app 提供自動更新功能的全家桶。

接下來分別介紹 electron-builder 的兩大功能:署名/打包/釋出 和 自動更新

署名/打包/釋出流程

想要將開發完成的 app 署名打包成安裝器 (installer) 釋出出去,需要進行以下幾個步驟

  • 署名
  • 打包
  • 釋出

electron-builder 的強大之處在於,以上幾個步驟可以一鍵完成,甚至包括打包成不同平臺版本 (etc. macOS, windows...)

但是,在讓 electron-builder 為我們完成以上步驟之前,它必須知道一系列資訊才能進行署名/打包/釋出一系列流程。它需要知道的資訊有:

  • 署名:署名證書在哪裡,以及使用署名證書的密碼等資訊
  • 打包:打包的安裝器面向的平臺,是 macOS, windows 還是 linux ,以及安裝器的格式等等
  • 釋出:要將打包好的安裝器釋出到的伺服器,那麼就需要和伺服器進行連結的驗證資訊

配置署名環節所需資訊

如果你進行署名打包的機器是 macOS 而且打包的安裝器對應的平臺也是 macOS 的話,electron-builder 會自動檢測你 keychain 裡面可用的署名證書然後自動使用,那麼就不需要手動配置署名資訊了。

要配置署名環節的各種資訊,有兩種方式(選其一即可,推薦在環境變數方式)

  • 在 package.json 裡設定
  • 在環境變數中設定

在 package.json 裡的設定方式

// 對於 windows 平臺的安裝器
"win": {
  "target": [
  {
  "signingHashAlgorithms": "sha1",
  "sign": "********",
  "certificationFile": "../../*****",
  "certificatePassword": "******"
  }
  ]
},

// 對於 macOS 平臺的安裝器
"mac": {
  "identity": "****" // The name of certificate to use when signing.
  },

複製程式碼

在環境變數中配置

Env Name Description
CSC_LINK The HTTPS link (or base64-encoded data, or file:// link, or local path) to certificate (*.p12 or *.pfx file). Shorthand ~/ is supported (home directory).
CSC_KEY_PASSWORD The password to decrypt the certificate given in CSC_LINK.
CSC_NAME macOS-only Name of a certificate (to retrieve from login.keychain). Useful on a development machine (not on CI) if you have several identities (otherwise don't specify it).
CSC_IDENTITY_AUTO_DISCOVERY true or false. Defaults to true — on a macOS development machine valid and appropriate identity from your keychain will be automatically used.
CSC_KEYCHAIN The keychain name. Used if CSC_LINK is not specified. Defaults to system default keychain.

注意:如果你是在 macOS 上打包面向 windows 平臺的安裝器,必須增加兩個不同的環境變數 WIN_CSC_LINK 和 WIN_CSC_KEY_PASSWORD

配置打包環節所需資訊

所謂打包環節所需資訊,就是指定安裝器(installer)的一系列配置資訊。比如說執行環境,安裝器格式,版權資訊,安裝器命名等等。這些資訊都是在 package.json 中配置。比如:

"win": {
  "target": [
  {
  "target": "nsis",
  "arch": [
  "x64",
  "ia32"
  ],
  ......
  }
  ]
},

"mac": {
  "category": "your.app.category.type",
  "target": [
  "zip",
  "dmg"
  ],
  },
複製程式碼

更多詳細配置,請參考

配置釋出環節所需資訊

署名,打包完成後的安裝器需要上傳發布到伺服器(比如說S3),那麼electron-builder就需要將連結伺服器的驗證資訊(比如賬號/密碼,或者各種 Token 等等)。

由於釋出的伺服器種類各異,所以針對不停的伺服器,配置的方式不盡相同

Bintray

通過Bintray釋出的話,需要一個 API key,這個API key 可以從使用者主頁獲取到("Edit Your Profile" -> API Key),將這個 API key 配置到環境變數 BT_TOKEN 即可

GenericServer

Generic 方式是針對可以直接上傳不需要驗證的伺服器,無需格外配置資訊。

GithubOptions

使用GitHub釋出伺服器的話,也需要一個TOKEN,這個TOKEN可以在GitHub上建立,可以參考GitHub Token 建立方法。獲取到這個Token之後,將它放到環境變數 GH_TOKEN 中既可。

S3Options

如果使用 Amazon S3 作為釋出伺服器的話,還需要額外安裝一個 electron-publisher-s3 模組(可以通過npm 或者 yarn 來安裝)

同樣的使用 Amazon S3 也需要驗證,在 AWS 上獲取你的驗證資訊,獲取到你在AWS上的 KEY ID 和 ACCESS_KEY 之後,然後分別放到環境變數 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY 裡面。或者你也可以放到 ~/.aws/credentials 裡面。

SpacesOptions

如果你使用 DigitalOcean Spaces 作為釋出伺服器的話,獲取到 access key 之後,然後在放到環境變數 DO_KEY_ID 和 DO_SECRET_KEY 裡面即可

署名/打包/釋出 一鍵完成

上面的資訊都配置好了的話,執行以下命令

$ build --publish

即可一鍵完成 署名/打包/釋出 流程

更多詳細資訊可以參考官網 CLI詳細說明

自動更新功能

electron app 的自動更新方案,可以大概分為以下兩種:

  • 有更新伺服器 (with update server) 的方案
  • 無更新伺服器(without update server)的方案

electron-updater 就是針對沒有更新伺服器的情況而生的解決方案。(PS:有更新伺服器的解決方案,可以通過electron自帶的autoUpdater來實現,具體的解決方案會在文章最後說明,在這裡主要講解electron-builder全家桶的使用方法)

在 electron-builder 中,這個叫做 electron-updater 的模組與 electron-builder 本體不同,它是一個 runtime-dependency ,也就是放在package.json的dependencies裡面的一個模組(PS: 而 electron-builder 是放在devDependencies裡面的)

electron-updater 功能強大之處在於,它支援多種無伺服器自動更新方案。這裡的無伺服器並不是指的真的沒有伺服器。具體來說就是在這種方案裡沒有計算伺服器 (eg. EC2),只有靜態檔案伺服器 (eg. S3)

electron-updater 模組通過檢測靜態檔案伺服器上面的最新release版本號,將它與本地版本號進行對比,從而得知是否需要自動更新。

話不多說,我們直接來看程式碼

const electron = require("electron");
const updater = require("electron-updater");
const autoUpdater = updater.autoUpdater;

autoUpdater.setFeedURL({
  provider: "generic", // 這裡還可以是 github, s3, bintray
  url: "https://gitlab.com/_example_repo_/-/jobs/artifacts/master/raw/dist?job=build"
});

autoUpdater.on('update-available', function (info) {
  console.log('Update available.');
});

複製程式碼

僅用兩行就完成了最基本的新版本的檢測機制,更多詳細的API可以參考官方文件

附錄:有更新伺服器的自動更新方案

帶有更新伺服器的自動更新方案主要由 electron 自帶的 autoUpdater 和 外部更新伺服器組成

常用的第三方服務有

  • Hazel - 是一個開源的 update server. 主要利用了 Github 的 release tag 來進行新版本的釋出通知。
  • Nuts – 也是一個開源的 update server, 也是利用了 Github 的 release tag 來進行新版本的釋出通知。不同的是,它可以將 新版本快取到本地硬碟,同時還支援 private repo。同時 Heroku 裡面提供的 update server 就是 Nuts,在 Heroku 裡面可以輕鬆啟動一個 Nuts 服務。
  • electron-release-server – 提供了一個 dashboard 來監控 release
  • Nucleus - 這是一個由 Atlassian 公司維護的 update server, 它可以同時支援多個 app 和 channel。而且因為是通過靜態檔案伺服器實現的,所以大大減少了計算消耗。

大家可以根據自己的需求來選擇搭建自己的更新伺服器,具體做法可以參考各自的 GitHub 。

而在 app 方面,只需要增加以下程式碼,就可以實現最基本的更新檢測


var app = require('app');
var os = require('os');
var autoUpdater = require('auto-updater');

var platform = os.platform() + '_' + os.arch();
var version = app.getVersion();

autoUpdater.setFeedURL('http://download.myapp.com/update/'+platform+'/'+version);

複製程式碼

筆者部落格

相關文章