はじめに
今回は、no.1 markdown editor で実装している自動アップデート機能を紹介します。
この実装は、アプリを裏で自動更新して置き換える方式ではありません。
やっているのは、起動時に最新版を確認し、今の OS と CPU に合ったインストーラを選んで、正しいダウンロード先へ案内する という仕組みです。
この方式にすると、実装を複雑にしすぎず、ユーザーにも
- Windows 用はどれ?
- macOS 用はどれ?
- x64 と arm64 のどっち?
と悩ませずに済みます。
全体の流れ
更新フローは次のようになっています。
- アプリ起動時に更新チェックを呼ぶ
- Tauri から Rust の
check_for_app_updateを呼ぶ - Rust 側で GitHub Releases の
latestAPI を取得する - 現在バージョンと最新版を semver で比較する
- assets から OS / CPU に合うファイルを 1 つ選ぶ
- 更新があればダイアログを表示し、
Download Latestで URL を開く
起動時の呼び出しはとてもシンプルです。
useEffect(() => {
void maybeRunAutomaticUpdateCheck()
}, [])
毎回チェックしないようにする
起動のたびに GitHub API を叩くと少しうるさいので、24 時間のクールダウンを入れています。
あわせて、次の状態を保存しておくと扱いやすくなります。
autoCheckEnabledlastCheckedAtskippedVersion
これで、自動チェックは静かに動かしつつ、必要なときだけ通知できます。
バージョン比較は semver で行う
GitHub の tag は v0.16.1 のような形になりやすいので、比較前に正規化しておきます。
たとえば、
v0.16.1V0.16.10.16.1
を同じ形式にそろえてから semver で比較します。
こうしておくと、0.9.0 と 0.10.0 のようなケースも安全に扱えます。
OS ごとに asset を選ぶ
今回の実装でいちばん大事なのはここです。
GitHub Releases には複数の asset があるので、ファイル名を見ながら、今の環境に合うものを自動で選びます。
優先順位は次の通りです。
| OS | 優先順位 |
|---|---|
| Windows |
.msi > .exe
|
| macOS | .dmg |
| Linux |
.AppImage > .deb > .rpm
|
さらに、ファイル名に含まれる token も見ます。
-
windows/macos/linux -
x64/x86_64/amd64 -
arm64/aarch64
別 OS 向けや別アーキテクチャ向けと判断できるものは除外し、最後に一番スコアが高い asset を選びます。
Rust 側のイメージはこんな感じです。
let selected_asset = select_best_asset(
&latest_release.assets,
current_update_platform(),
current_update_architecture(),
);
この形にしておくと、たとえば Windows x64 では x64.msi を優先し、macOS では dmg、Linux では AppImage を自然に選べます。
Download Latest でやっていること
ここは誤解されやすいので、はっきり書いておきます。
今回の実装では、アプリ内で更新ファイルを直接ダウンロードしていません。
Download Latest を押したときにやっているのは次のどちらかです。
- 選ばれた asset の URL を開く
- 適切な asset が見つからなければ release page を開く
つまり、アプリの役割は
- 更新があるか調べる
- 正しいファイルを選ぶ
- 正しい配布先へ案内する
までです。
実際のダウンロードは OS や既定ブラウザに任せています。
export function getReleaseDownloadUrl(release) {
return release.downloadUrl ?? release.releaseUrl
}
この方式なら、進捗管理や自動置き換えまで抱え込まずに、まず使いやすい更新導線を作れます。
手動チェックとスキップ機能も入れる
自動チェックだけだと少し足りないので、手動チェックの入口も用意しています。
- About / Updates パネル
- コマンドパレット
さらに、更新ダイアログには次の操作を用意しています。
Download LatestSkip This VersionCancel
特に Skip This Version は重要です。
- 自動チェック時は、スキップ済みバージョンなら再表示しない
- 手動チェック時は、スキップ済みでも表示する
こうしておくと、しつこくならず、でも必要なときはいつでも確認できます。
まとめ
今回の構成は、次の点でかなり実用的でした。
- GitHub Releases をそのまま更新基盤にできる
- OS / CPU ごとの選択をアプリ側で吸収できる
- ユーザーにファイル選択をさせなくて済む
- 完全自動更新よりシンプルで保守しやすい
Tauri アプリで更新機能を入れたいとき、最初から完全自動更新まで作り込まなくても、
「自動で確認して、正しい配布物へ迷わず案内する」 ところから始めるだけで十分価値があります。
