ElectronのautoUpdater
Electronには、アプリの新しいバージョンをダウンロードして
更新する機能が用意されています。
https://www.electronjs.org/docs/api/auto-updater
Electronアプリからこの機能を使うには本来、
最新版アプリの情報を返すアップデートサーバーが必要になるのですが、
GitHubのReleasesに最新アプリバイナリを置いているアプリ
については、
Electron公式がアップデートサーバーを用意してくれているので、
アプリ側の修正だけで、簡単に自動アップデート機能を組み込めるようになっています。

(ここだよ、ここ)
update.electronjs.org
こちらが公式が用意しているサーバーで、
update.electronjs.org (GitHubにリダイレクト)
このサーバーは、次のパターンのURLを叩くと、GitHubの最新リリースの情報を取得して返します。
https:
例えば、GitHubのレポジトリが"taku-o/myukkurivoice"で、
現在実行中のアプリのバージョンが"0.13.6"だとすれば、次のURLになりますね。
このURLをブラウザで開くと、JSON形式で最新リリースのデータが返ってくるのが分かります。
https://update.electronjs.org/taku-o/myukkurivoice/darwin-x64/0.13.6
{"name":"0.13.7","notes":"- \"MYukkuriVoice について\"ダイアログの表示を修正。\r\n - ビルド時の...
対応している環境
update.electronjs.orgで対応している環境はLinux環境以外です。
Linuxは駄目かー。そっかー、残念ですね。
macOSのアプリについては、アプリにDeveloper ID Applicationの署名が必要。
実行中のアプリ、そして、ダウンロードする更新アプリ、両方に署名が必要です。
(アプリに署名がされていないと、自動アップデートがエラーになる。)
Error: Code signature at URL file:///Users/user/Library/Caches/jp.nanasi.myukkurivoice.ShipIt/update.TdmmDN0/
MYukkuriVoice-darwin-x64/MYukkuriVoice.app/ did not pass validation: コードオブジェクトがまったく署名されていません
Error: Could not get code signature for running application
Catalinaでは、アップル公証(Notarization)も必要かも?
調べていません。
わざわざ公証の実装を外してまで検証しないよ。
面倒だからね。仕方ないね(^_^)/
更新用のアプリをReleasesに置く
更新用のアプリは、zipで固めてGitHubのReleasesに置いておきます。
https://github.com/taku-o/myukkurivoice/releases/tag/0.13.8
1. バージョン番号のReleasesタグを作る(0.13.8 とか)
2. 更新用のアプリをzip形式にしてアップロードする
3. zipファイルのファイル名は、例えば、AppName-darwin-x64.zip のような形式にする

update.electronjs.orgは、Windows環境とMac環境に対応していますが、
いくつかアップロードされているzipファイルのうち、
どのzipファイルが、どの環境用のものかは、ファイル名から判断されています。
なので、zipファイル名には、mac, darwin, win32-x64など対応環境を示す文字を入れておきましょう。
mac
darwin
osx
win32-ia32
win32-x64
Electronアプリへの組み込み(自動的に更新処理)
Electronアプリのコードにアプリ自動更新の機能を組み込みます。
npmでupdate-electron-appを入れておいて、
npm install update-electron-app
アプリ側で、このコードを呼び出す。
require('update-electron-app')()
簡単!
Electronアプリへの組み込み(任意のタイミングで更新)
上の実装は簡単なのですが、しかし、ドキュメントによると、
10分毎に更新をチェックしにいくようです。
https://www.electronjs.org/docs/tutorial/updates
なんてこった(>_<)!
そんなにアプリを頻繁に更新するわけないぞ(>_<)!
1ヶ月に1回更新できたらマシな方だ(>_<)!
そういう場合は、checkForUpdates()を手動で叩いて、
好きな頻度で更新するか、メニューから更新できるようにしたら良いでしょうな。
autoUpdater.checkForUpdates();
import {app, dialog, autoUpdater} from 'electron';
autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => {
const dialogOptions = {
type: 'info',
buttons: ['Restart', 'Later'],
title: 'Application Update',
message: process.platform === 'win32' ? releaseNotes : releaseName,
detail: '新しいアプリのダウンロードが完了しました。アプリを再起動して更新を適用します。',
};
dialog.showMessageBox(dialogOptions)
.then((result) => {
const btnId: number = result.response;
if (btnId === 0) {
autoUpdater.quitAndInstall();
}
});
});
autoUpdater.on('error', (err: Error) => {
const dialogOptions = {
type: 'error',
title: 'Application Version Check Error.',
message: 'アプリのアップデート中にエラーが発生しました。',
buttons: ['OK'],
defaultId: 0,
cancelId: 0,
};
dialog.showMessageBox(dialogOptions);
});
const server = 'https://update.electronjs.org';
const feed = `${server}/taku-o/myukkurivoice/${process.platform}-${process.arch}/${app.getVersion()}`;
autoUpdater.setFeedURL({
url: feed,
serverType: 'json',
});
autoUpdater.checkForUpdates();
いったんcheckForUpdates()を実行すると、
アプリの更新処理をストップ出来ないらしく、
実行前にユーザーに確認ダイアログを出しておいた方が良さそうです。
あるいは、今動作しているアプリのバージョンが最新かどうか確認しておいてから、
アプリを更新しても良いか聞いておきましょう。
autoUpdaterが間違ったファイルをダウンロードする(1敗)
ElectronのautoUpdaterは、おおよそ次の順番で処理しています。
(Mac環境)
1. 実行中のアプリの署名の確認
2. 実行中のアプリが最新版かどうかチェック
3. 最新アプリのダウンロード
4. zipファイルの解凍
5. 最新アプリの署名の確認
6. アプリの入れ替え
update.electronjs.orgはこんな実装(↓)になっているので、
データファイルなどの名前に"mac"の文字が入っていると、
更新アプリでなく、間違ったファイルをダウンロードすることがありますね。
(1敗)
# https:
const assetPlatform = fileName => {
if (/.*(mac|darwin|osx).*\.zip/i.test(fileName)) return 'darwin-x64'
if (/win32-ia32/.test(fileName)) return 'win32-ia32'
if (/win32-x64|(\.exe$)/.test(fileName)) return 'win32-x64'
return false
}
ダウンロードされたzipファイルは、
次のような場所に保存された後、解凍され、
その後、アプリの署名の検証が行われます。
/Users/user/Library/Caches/xx.xx.bundleid.ShipIt/update.QCBggxR
なので、誤ったファイルをダウンロードしていて、
署名エラーが発生している時は、
このディレクトリを監視していれば、問題を追えます。
(エラーになった時、すぐ消されちゃうみたいですけど。)
if (/win32-x64|(\.exe$)/.test(fileName)) return 'win32-x64'
試していませんけれど、このコードを見る限り、
Windows環境はexe形式もいけるみたいですね。
自己解凍形式がサポートされているのかな?
終わり
MacのElectronアプリだったらさ、
自動更新機能を組み込まなくても、Mac App Storeに出せば良いじゃない?
そんなふうに考えていた時期が俺にもありました。
どうも駄目なレビュアーに当たった気がします。
審査が通らない。
話が通じない。
そろそろ審査アプリのバンドルIDを変更して、
レビューする人を切り替えようかと考え始めています。
(あくまでも自分は悪くないと決めつけるスタイル)