メインコンテンツへ飛ぶ

アプリケーションの更新

Electron アプリケーションの自動更新を行うには、いくつかの方法があります。 The easiest and officially supported one is taking advantage of the built-in Squirrel framework and Electron's autoUpdater module.

クラウドオブジェクトストレージ (サーバーレス) の使用

シンプルなサーバーレス更新フローの場合、Electron の autoUpdater モジュールは、最新リリースのメタデータを格納する静的ストレージの URL を指定すれば更新が利用可能かどうかを確認できます。

新しいリリースを利用可能にしたら、このメタデータをリリース本体と一緒にクラウドストレージに公開する必要があります。 メタデータの形式は macOS と Windows で異なります。

リリースのメタデータの公開

Electron Forge を使用する場合、macUpdateManifestBaseUrl を使用すれば ZIP Maker (macOS) から、remoteReleases を使用すれば Squirrel.Windows Maker (Windows) からメタデータのアーティファクトを公開することで、静的ファイルストレージの更新を設定できます。

エンドツーエンドの例については、Forge の S3 からの自動更新 のガイドを参照してください。

手動公開

macOS では、Squirrel.Mac は以下の JSON 形式の releases.json ファイルを読み取ることで更新を受信できます。

releases.json
{
"currentRelease": "1.2.3",
"releases": [
{
"version": "1.2.1",
"updateTo": {
"version": "1.2.1",
"pub_date": "2023-09-18T12:29:53+01:00",
"notes": "Theses are some release notes innit",
"name": "1.2.1",
"url": "https://mycompany.example.com/myapp/releases/myrelease"
}
},
{
"version": "1.2.3",
"updateTo": {
"version": "1.2.3",
"pub_date": "2024-09-18T12:29:53+01:00",
"notes": "Theses are some more release notes innit",
"name": "1.2.3",
"url": "https://mycompany.example.com/myapp/releases/myrelease3"
}
}
]
}

Windows では、Squirrel.Windows はビルドの過程で生成された RELEASES ファイルを読み取ることで更新を受信できます。 このファイルには、更新する .nupkg 差分パッケージの詳細が記載されています。

RELEASES
B0892F3C7AC91D72A6271FF36905FEF8FE993520 electron-fiddle-0.36.3-full.nupkg 103298365

これらのファイルは、アプリのプラットフォームとアーキテクチャを考慮したフォルダー構造の配下の、リリースと同じディレクトリに配置する必要があります。

以下がその例です。

my-app-updates/
├─ darwin/
│ ├─ x64/
│ │ ├─ my-app-1.0.0-darwin-x64.zip
│ │ ├─ my-app-1.1.0-darwin-x64.zip
│ │ ├─ RELEASES.json
│ ├─ arm64/
│ │ ├─ my-app-1.0.0-darwin-arm64.zip
│ │ ├─ my-app-1.1.0-darwin-arm64.zip
│ │ ├─ RELEASES.json
├─ win32/
│ ├─ x64/
│ │ ├─ my-app-1.0.0-win32-x64.exe
│ │ ├─ my-app-1.0.0-win32-x64.nupkg
│ │ ├─ my-app-1.1.0-win32-x64.exe
│ │ ├─ my-app-1.1.0-win32-x64.nupkg
│ │ ├─ RELEASES

リリースのメタデータの読み取り

最も簡単なメタデータの利用方法は、autoUpdater を設定し、ドロップインの Node.js モジュールである update-electron-app をインストールすることです。これはネイティブのダイアログでユーザーにプロンプ​​トを表示します。

静的ストレージの更新の場合は、updateSource.baseUrl 引数にリリースのメタデータファイルを格納するディレクトリを指定します。

main.js
const { updateElectronApp, UpdateSourceType } = require('update-electron-app')

updateElectronApp({
updateSource: {
type: UpdateSourceType.StaticStorage,
baseUrl: `https://my-bucket.s3.amazonaws.com/my-app-updates/${process.platform}/${process.arch}`
}
})

update.electronjs.org の利用

Electron チームは update.electronjs.org をメンテナンスしています。これは、Electron を自己更新するためのオープンソースウェブサービスです。 このサービスは次の条件を満すElectronアプリ用に設計されています。

  • macOSまたはWindowsで動作するアプリである。
  • アプリはGitHubのパブリックなリポジトリである。
  • ビルドが GitHub の Releases で公開されている
  • ビルドが コード署名 されている (macOS のみ)

このサービスを使う最も簡単な方法はupdate-electron-appをインストールすることで、update.electronjs.orgをつかって、事前調整されたNode.js モジュールを使う方法です。

Node.js パッケージマネージャを使用して、このモジュールをインストールします。

npm install update-electron-app

そして、アプリのメインプロセスファイルから以下のようにアップデータを呼び出します。

main.js
require('update-electron-app')()

デフォルト設定で、このモジュールはアプリの起動時に更新をチェックします。または10分毎にチェックします。 アップデートがみつかったとき、自動的にバックグラウンドでダウンロードします。 そのダウンロードが完了したときに、ダイアログを表示してユーザにアプリの再起動許可を取ります。

設定をカスタマイズしたい場合、update-electron-app にオプションを渡す か、アップデートサービスを直接使用 できます。

他の更新サービスを利用する

プライベートの Electron アプリケーションを開発している場合、または GitHub リリースにリリースを公開していない場合は、独自のアップデートサーバーを実行する必要があるかもしれません。

ステップ 1: 更新サーバをデプロイする

ニーズに応じて、次のいずれかから選択できます。

  • HazelVercel 上に無料デプロイできる、非公開またはオープンソースのアプリのための更新サーバーです。 それは GitHub Releases から引き出され、GitHub の CDN の力を活用します。
  • NutsGitHub Releases も使用しますが、アプリの更新をディスクにキャッシュし、プライベートリポジトリをサポートします。
  • electron-release-server – リリースを処理するためのダッシュボードを提供します。リリースを GitHub で作成する必要はありません。
  • Nucleus – Atlassian がメンテナンスしている Electron アプリのための完全なアップデートサーバー。 複数のアプリケーションとチャンネルをサポートします。サーバーのコストを最小限に抑えるために静的ファイルストアを使用します。

更新サーバをデプロイしたら、Electron の autoUpdater モジュールを使って、アップデートを受信して適用するようアプリのコードに設置できます。

ステップ 2: アプリで更新を受け取る

まず、メインプロセスのコードで必要なモジュールをインポートします。 以下のコードはサーバソフトウェアによって異なる場合がありますが、Hazel を使用する場合は前述の通りに機能します。

実行環境を確認すること!

以下のコードは、開発時ではなく、パッケージ化されたアプリでのみ実行してください。 You can use the app.isPackaged API to check the environment.

main.js
const { app, autoUpdater, dialog } = require('electron')

Next, construct the URL of the update server feed and tell autoUpdater about it:

main.js
const server = 'https://your-deployment-url.com'
const url = `${server}/update/${process.platform}/${app.getVersion()}`

autoUpdater.setFeedURL({ url })

最後のステップとして、更新を確認します。 以下の例では、毎分確認します。

main.js
setInterval(() => {
autoUpdater.checkForUpdates()
}, 60000)

Once your application is packaged, it will receive an update for each new GitHub Release that you publish.

ステップ 3: アップデートが利用可能な場合にユーザに通知する

アプリケーションの基本的な更新メカニズムを設定したので、更新があるとユーザに通知されるようにする必要があります。 This can be achieved using the autoUpdater API events:

main.js
autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => {
const dialogOpts = {
type: 'info',
buttons: ['Restart', 'Later'],
title: 'Application Update',
message: process.platform === 'win32' ? releaseNotes : releaseName,
detail:
'A new version has been downloaded. Restart the application to apply the updates.'
}

dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) autoUpdater.quitAndInstall()
})
})

Also make sure that errors are being handled. これは stderr にログを出力するための例です。

main.js
autoUpdater.on('error', (message) => {
console.error('There was a problem updating the application')
console.error(message)
})
更新を手動でハンドリングする

自動更新によるリクエストは直接管理されていないため、対応が難しい状況が発生することがあります (更新サーバーが認証下にある場合など)。 url フィールドは file:// プロトコルをサポートしています。つまりローカルディレクトリから更新を読み込むことで、工夫次第でサーバ通信特有の問題を回避できます。 こちらにその動作例があります

Update server specification

For advanced deployment needs, you can also roll out your own Squirrel-compatible update server. For example, you may want to have percentage-based rollouts, distribute your app through separate release channels, or put your update server behind an authentication check.

Squirrel.Windows and Squirrel.Mac clients require different response formats, but you can use a single server for both platforms by sending requests to different endpoints depending on the value of process.platform.

main.js
const { app, autoUpdater } = require('electron')

const server = 'https://your-deployment-url.com'
// e.g. for Windows and app version 1.2.3
// https://your-deployment-url.com/update/win32/1.2.3
const url = `${server}/update/${process.platform}/${app.getVersion()}`

autoUpdater.setFeedURL({ url })

Windows

A Squirrel.Windows client expects the update server to return the RELEASES artifact of the latest available build at the /RELEASES subpath of your endpoint.

For example, if your feed URL is https://your-deployment-url.com/update/win32/1.2.3, then the https://your-deployment-url.com/update/win32/1.2.3/RELEASES endpoint should return the contents of the RELEASES artifact of the version you want to serve.

https://your-deployment-url.com/update/win32/1.2.3/RELEASES
B0892F3C7AC91D72A6271FF36905FEF8FE993520 https://your-static.storage/your-app-1.2.3-full.nupkg 103298365

Squirrel.Windows does the comparison check to see if the current app should update to the version returned in RELEASES, so you should return a response even when no update is available.

macOS

When an update is available, the Squirrel.Mac client expects a JSON response at the feed URL's endpoint. This object has a mandatory url property that maps to a ZIP archive of the app update. All other properties in the object are optional.

https://your-deployment-url.com/update/darwin/0.31.0
{
"url": "https://your-static.storage/your-app-1.2.3-darwin.zip",
"name": "1.2.3",
"notes": "Theses are some release notes innit",
"pub_date": "2024-09-18T12:29:53+01:00"
}

If no update is available, the server should return a 204 No Content HTTP response.