Electronのビルドをデプロイし、リリース用ページを公開した直後、コーヒーが淹れ終わる前に最初のサポートチケットが届きます。あるユーザーは「アップデートが見つからない」と言い、別のユーザーは「ダウンロードはできたがインストールできない」と訴えます。さらに別のユーザーは、認証フローが壊れた古いバイナリを使い続けており、それなのにあなたのログには有用な情報がほとんど残っていません。
それが、 Electronアプリの自動アップデートにおける厳しい現実です。APIによるアップデーターは、全体の一部に過ぎません。プロダクション環境でのリリースには、プラットフォームの署名、トランスポートポリシー、マニフェスト、ホスティング、ライフサイクルイベント、オブザーバビリティ、ロールアウト制御、そしてロールバック経路が必要です。これらを一つでも「オプション」と考えてしまうと、日常的なパッチ適用が、一晩で重大なインシデントへと発展しかねません。
目次
- このガイドを書くきっかけとなった、午前2時のアップデート・インシデント
- Electron Updater の最適な実装パスの選択
- メインプロセスでの Auto-Update フローの実装
- 署名済みリリースとマニフェストのための CI/CD 構築
- ロールアウト、Channel、およびロールバック戦略
- セキュリティコントロールとしての Auto-Update
- 本番環境のアップデート運用手順書とチェックリスト
このガイドのきっかけとなった、午前2時のアップデート事故
リリースはCIを通過し、一見いつも通りに見えました。しかし金曜の深夜、ある開発者が署名のないElectron buildをプッシュしてしまい、publishジョブが十分なアセットをuploadしたことで、リリースが完了したように見えてしまいました。テスト環境ではアプリが起動しましたが、本番環境のインストール済みビルドからアップデートパスを試した人はいませんでした。
午前2時8分、PagerDutyがオンコールエンジニアにアラートを飛ばしました。一部のユーザーで新しい認証フローが失敗し、アップデートを受け取ったユーザーがサインインを完了できない状態になっていました。一方で、アップデーターがアーティファクトを検証・インストールできなかったため、以前のバージョンに留まっているユーザーもいました。一部の顧客には壊れたリリースが届き、残りのユーザーは明確な理由もなく異なるバージョンを実行しているという状況でした。
調査では、以下の5つのチェックを行いました:
- リリースフィードの確認 バイナリは存在していましたが、期待されるメタデータがどのクライアントに配信すべきかを明確に示していませんでした。マニフェストはリリースpipelineとインストール済みクライアント間の契約であり、単なるオプションのアップロード詳細ではありません。
- 署名の検証 リリースが正しく署名されていなかったため、影響を受けたプラットフォームで検証に失敗しました。署名が欠落している、または無効な場合は、公開をブロックする必要があります。
- クライアントログの比較 アップデートのエラーが中央のテレメトリに届きませんでした。アプリケーションがイベントを飲み込んでそのまま実行を続けたため、チームは確かな証拠を得られませんでした。
- ロールアウト制御を確認してください。 内部チャネルやステージング用のコホートが存在しませんでした。対象となるすべてのクライアントが同じフィードを使用していたため、封じ込めができず障害が拡散しました。
- ロールバックを検索します。 チームには、以前のバージョンを再公開したり、壊れたリリースからクライアントを遠ざけたりするための、テスト済みの手順がありませんでした。
Electronの公式ドキュメントには、プラットフォームの制限が明記されています。 Linuxには組み込みの自動アップデートサポートがなく、また、macOSのアップデートリクエストは App Transport Securityの要件を満たす必要があります。ドキュメントでは、信頼性の高いmacOSのアップデートとリリース検証には、署名が前提条件であることも示されています。 ElectronのautoUpdaterドキュメントでは、 API の制約が定義されており、リリースシステム側で周囲の運用制御を強制する必要があります。
ポストモーテムからの教訓: 何が起きたかを説明できないアップデーターは、テレメトリが欠落したリモートインストール試行に過ぎません。
その代償はエンジニアリング工数に留まりませんでした。顧客はデスクトップクライアントへの信頼を失い、サポートは一貫性のない挙動への説明に追われ、チームは翌営業日に、本来インシデント前に構築しておくべきだったリリースプロセスを再構築するために時間を費やすことになりました。
自動アップデートを一つの 運用システムとして捉えてください。署名はリリースゲートであり、マニフェストはクライアントとの契約を定義し、ロールアウトチャネルは影響範囲を制限します。そしてロールバックは、緊急時にその場しのぎで考案するものではなく、テスト済みのパスとして存在すべきものです。
最適なElectron Updaterの選択肢
午前2時、誤ったアップデーターの選択は運用上の問題へと発展します。ネイティブバイナリのアップデートには、署名、マニフェスト、インストーラー、およびロールバックの処理が不可欠です。一方、レンダラーのみのJavaScriptやCSSの変更は、異なるパスを辿ります。ホスティングの制約も重要です。GitHubでホストされている小規模なプロジェクトには、エンタープライズ向けの配信サービスと同じリリース制御は必要ありません。
署名済みアーティファクトの公開を伴うelectron-builderを使用しているプロジェクトでは、 electron-updater が実用的なデフォルトとなるのが一般的です。そのエコシステムは、公開先、リリースマニフェスト、アーティファクトのダウンロード、および次回の起動時のインストールをカバーしています。複数のホスティングモデルをサポートしていますが、署名、フィードの可用性、チャネルポリシー、ロールアウト制御、およびモニタリングの責任は依然としてチームにあります。 Capgo向けElectron updaterの統合 ネイティブリリースと並行して、Webレイヤーのbundleを配信するハイブリッドモデルを検討する際に重要となります。
update-electron-app GitHub Releases周辺に最小限の統合を行いたいチームに適しています。起動時と一定の間隔でチェックを行うため、セットアップは簡単ですが、高度なチャンネル選択、段階的なトラフィック展開、カスタムロールバックルールなどの柔軟性は低くなります。GitHub Releasesとその可用性が運用要件に合致していれば、小規模なリリースプロセスには十分なパッケージです。
| オプション | ホスティング制御 | 署名サポート | チャンネルと段階的ロールアウト | メンテナンス負荷 |
|---|---|---|---|---|
| electron-updater | S3、GitHub、汎用HTTPS、その他の配信先 | パッケージ化されたリリース署名と統合可能 | 強固な基盤。カスタムポリシーは通常フィード周辺で管理 | 中程度 |
| Electronアプリのアップデート | 主にシンプルな GitHub Releasesワークフロー | Electron標準の署名モデルを使用 | 周辺サービスを追加しない限り限定的 | 低い |
| Squirrel.Windows または Squirrel.Mac | プラットフォーム指向の配信フロー | プラットフォームの署名要件に依存 | 可能だが、通常は追加のリリース基盤が必要 | レガシーアプリの場合は中程度 |
| カスタムサービス | マニフェスト、認可、コホート、フィードを完全に制御 | 検証設計と鍵管理の全権限を保持 | 最大限の柔軟性 | 高い |
| Capgo による Live Update | Webレイヤーのbundle配信を管理 | 独自のupdaterと配信モデルを使用 | オーディエンスターゲティングとチャンネル配信 | ネイティブバイナリの更新と運用モデルを分離 |
リリース承認、テナント指定、監査ログ、または規制遵守のデプロイ規則により実装コストが正当化される場合は、Hazel、Nuts、または社内フィードなどのカスタムサービスが適しています。ただし、継続的な運用責任が伴います。チームはマニフェストのセマンティクス定義、署名鍵の保護、クライアント互換性の維持に加え、ダウンロード失敗、リリース拒否、ロールバック時の挙動をテストする必要があります。
Live updatesを使用すると、ネイティブシェルを再ビルドせずにレンダラーのみの変更を配信できます。ただし、Electron本体、ネイティブモジュール、権限、またはインストーラーの挙動が変更される場合は、バイナリアップデートの代わりにはなりません。 カスタムのロールアウトロジックが必要でない限り、electron-updaterを使用してください。 カスタムロジックが必要な場合は、ダウンロードや差分アップデートの挙動をゼロから作り直すのではなく、確立されたマニフェストやアーティファクトの規約に基づいて構築してください。信頼できるパスとは、緊急時でもチームがObserve、ステージング、およびロールバックできる仕組みのことです。
メインプロセスにおける自動アップデートフローの実装
アップデートの確認とインストールはメインプロセスが担当すべきです。レンダラーはステータスを表示することはできますが、実行可能なアップデートを信頼するかどうかや、アプリケーションを終了させるタイミングを決定すべきではありません。
まず公開先(publish target)を設定する
最小限の electron-builder 設定例は以下の通りです:
{
"build": {
"appId": "com.example.desktop",
"publish": [
{
"provider": "s3",
"bucket": "example-electron-releases",
"channel": "stable"
}
],
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true
}
}
}
beta と stable のフィードは分けて管理してください。チャンネルはリリース・ポリシーであり、UI上のラベルではありません。各チャンネルは、正しい署名済みアーティファクトとマニフェストに解決される必要があります。
チェックのスケジュール設定とライフサイクルイベントの公開
呼び出しを checkForUpdates() 起動時のみに限定するのは、本番環境でよくある間違いです。ユーザーはアプリケーションを数日間開いたままにすることもあるため、メインプロセスには制御されたインターバルと、オフライン状態を考慮したリトライ戦略が必要です。
const { app, BrowserWindow, ipcMain } = require('electron');
const { autoUpdater } = require('electron-updater');
let mainWindow;
let isQuitting = false;
let retryDelay = 60 * 1000;
function sendUpdateStatus(status, payload = {}) {
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.webContents.send('update-status', { status, ...payload });
}
}
function scheduleUpdateCheck() {
setTimeout(async () => {
try {
await autoUpdater.checkForUpdates();
retryDelay = 60 * 1000;
} catch (error) {
sendUpdateStatus('error', { message: error.message });
retryDelay = Math.min(retryDelay * 2, 30 * 60 * 1000);
}
scheduleUpdateCheck();
}, retryDelay);
}
app.whenReady().then(() => {
mainWindow = new BrowserWindow({
webPreferences: {
preload: require('path').join(__dirname, 'preload.js')
}
});
autoUpdater.autoDownload = true;
autoUpdater.autoInstallOnAppQuit = false;
autoUpdater.on('checking-for-update', () => {
sendUpdateStatus('checking');
});
autoUpdater.on('update-available', info => {
sendUpdateStatus('available', { version: info.version });
});
autoUpdater.on('download-progress', progress => {
sendUpdateStatus('progress', { percent: progress.percent });
});
autoUpdater.on('update-downloaded', info => {
sendUpdateStatus('downloaded', { version: info.version });
});
autoUpdater.on('error', error => {
sendUpdateStatus('error', { message: error.message });
});
autoUpdater.checkForUpdates().catch(error => {
sendUpdateStatus('error', { message: error.message });
});
scheduleUpdateCheck();
});
ipcMain.handle('install-update', () => {
isQuitting = true;
autoUpdater.quitAndInstall(false, true);
});
app.on('before-quit', event => {
if (!isQuitting) {
return;
}
});
アップデートイベントの正確な挙動はプラットフォームやパッケージング構成によって異なるため、開発モードではなくインストール済みのアーティファクトでテストしてください。Electron のドキュメントでも、Windows における Squirrel の初回起動時などの起動タイミングに関する注意点が指摘されています。プラットフォーム固有の初期化が完了する前に、アップデートのチェックを実行しないでください。
処理をブロックせずにレンダラーへ情報を伝える
preload ブリッジは、限定的な API を公開すべきです:
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('updates', {
onStatus(callback) {
ipcRenderer.on('update-status', (_event, status) => callback(status));
},
install() {
return ipcRenderer.invoke('install-update');
}
});
レンダラー側のプログレスバーは、あえてシンプルに保つことができます:
window.updates.onStatus(status => {
const progress = document.querySelector('#update-progress');
const message = document.querySelector('#update-message');
if (status.status === 'progress') {
progress.hidden = false;
progress.value = status.percent;
message.textContent = `Downloading update, ${Math.round(status.percent)}%`;
}
if (status.status === 'downloaded') {
message.textContent = `Version ${status.version} is ready to install`;
}
if (status.status === 'error') {
message.textContent = 'The update could not be downloaded. We will retry later.';
}
});
アプリケーションに即時再起動が必要な強力な理由がない限り、本番環境ではユーザーの同意を得てからインストールを実行するようにしてください。まず、 isQuitting フラグを quitAndInstall()に設定してください。そうしないと、通常のウィンドウ終了ハンドラーがインストーラーの動作を妨げる可能性があります。

明示的なテストが必要な失敗例が2つあります。1つ目は、すでに実行中のクライアントが起動時だけでなく、 checkForUpdates() スケジュールに従って呼び出す必要がある点です。2つ目は、 error イベントがログやテレメトリに到達しなければならない点です。アプリが報告せずにエラーを飲み込んでしまうと、 アプリのトラブルシューティングのワークフローが、 エビデンスに基づいたものではなく、推測から始まってしまいます。
署名済みリリースとマニフェストのためのCI/CD構築
リリースパイプラインは、ユーザーが何をインストールするかを決定する「信頼できる唯一の情報源(Source of Truth)」です。ある開発者のマシンで動作するローカルビルドが成功したとしても、公開されたバイナリ、マニフェスト、署名、およびチャンネルがすべて同一のリリースを指しているとは限りません。
electron-builderのパブリッシュモデルでは、リリースのメタデータとアップデート対象がセットで扱われることが想定されています。多くの構成において、これは次のようなアーティファクトを意味します。 latest.yml Windows用、および latest-mac.yml macOS用として、プラットフォーム固有のパッケージとblockmapファイルが必要です。マニフェストが欠落していると、たとえバイナリが正しくてもクライアントから認識されません。
CIで署名を明示的に行う
GitHub Actionsの簡略化されたパターンは以下の通りです:
name: release
on:
push:
tags:
- "v*"
jobs:
build:
strategy:
matrix:
os: [macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run test
- run: npm run build
- name: Build and publish
shell: bash
env:
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
WIN_CSC_LINK: ${{ secrets.WIN_CSC_LINK }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: npx electron-builder --publish always
プラットフォーム固有のsecretを使用し、署名用リソースはリポジトリの外で管理してください。署名に失敗した場合は、誰かが手動でアップロードしてしまうような未署名のフォールバックを作成するのではなく、ジョブを停止させるべきです。
| 変数 | 用途 |
|---|---|
CSC_LINK |
macOSの証明書または証明書リファレンス |
CSC_KEY_PASSWORD |
macOS署名用リソースのパスワード |
WIN_CSC_LINK |
Windowsの証明書または証明書リファレンス |
AWS_ACCESS_KEY_ID |
権限を最小限に絞った公開用クレデンシャル |
AWS_SECRET_ACCESS_KEY |
公開用クレデンシャルとペアになるSecret |
publish設定では、プロバイダーとチャンネルを整合性を持って指定する必要があります:
{
"build": {
"publish": {
"provider": "s3",
"bucket": "example-electron-releases",
"channel": "stable",
"publishAutoUpdate": true,
"updaterCacheDirName": "example-desktop-updater"
}
}
}
公開前に、パッケージのバージョン、タグ、コミットSHA、およびスモークテストの結果に基づいてジョブを制御します。公開後は、フィードに期待通りのマニフェストが含まれているか、またそのマニフェストが当該ジョブで生成された正確なアーティファクトを指しているかを確認してください。 CI(継続的インテグレーション)の設定ガイド は、これらのチェックを形式化する場合に役立ちます。また、パイプラインのオーケストレーションを比較しているチームにとっても、 JenkinsとAnsibleを併用すべきタイミング.
を理解することは有益です。不完全なリリースを招きやすいコマンドは、意図的にシンプルに設計されています:
npx electron-builder --publish never
test -f dist/latest.yml
test -f dist/latest-mac.yml
find dist -name "*.blockmap" -print
これらのチェックは、署名済みのインストールテストに代わるものではありません。しかし、クライアントが検出するために必要なメタデータなしでバイナリをアップロードしてしまうといった、運用上のミスは防ぐことができます。
ロールアウト、チャンネル、およびロールバック戦略
リリースフィードは、単なるダウンロードフォルダではなく、デプロイ先のように動作させるべきです。 内部, ベータや 最新 各チャンネルは独立しており、それぞれ独自のmanifestと署名済みアーティファクトセットによって管理されます。プロモーション(昇格)は、クライアントがダウンロード中にファイルを上書きするのではなく、テスト済みのリリースをポリシー間で移動させるべきです。
チャンネルを分けることで、誤ってテストビルドを本番環境に適用してしまうことも防げます。アップデーターは、フィードを評価する前に、そのクライアントが内部向け、ベータ版、あるいは安定版のどのグループに属しているかを把握している必要があります。
広範囲に展開する前に、まずはcohortを活用しましょう
カスタムmanifestフィールドを使用して、段階的なデリバリーを表現できます:
version: 4.8.0
path: Example-Setup-4.8.0.exe
sha512: signed-artifact-hash
rolloutPercentage: 10
メインプロセスでユーザーごとに安定したバケットを割り当て、そのバケットを以下と比較します: rolloutPercentage. 割り当ての安定性は重要です。チェックのたびに対象・対象外の状態が入れ替わるユーザーがいると、挙動が予測できなくなり、サポートへの報告内容の解釈も困難になります。
リリースが観測期間を無事に通過した後にのみ、cohortを拡大してください。観測期間の長さは利用パターンに合わせて設定すべきですが、判断基準はカレンダー上の日付だけでなく、各種シグナルに基づくべきです。アップデートのチェック結果、ダウンロードの完了、起動時のヘルス状態、クラッシュ、レンダラーの例外、認証の成功などを追跡してください。
| シグナル | アクション | 理由 |
|---|---|---|
| フィードまたは署名エラーがチームの許容上限を超えた | ロールアウトを停止 | クライアントがリリースを検証または検出できない可能性があります |
| アップデート後の起動チェックに失敗 | フィードを元に戻す | バイナリのインストールは完了しても、起動時に失敗する可能性があります |
| プロモーション後にRenderer例外が増加 | 現在のコホートで停止 | ネイティブインストーラーは正常でも、新しいアプリケーション code が正常でない可能性があります |
| シグナルがリリース予算内に収まっている | コホートを拡大 | より広範な展開を裏付けるエビデンスがある |
ロールバックとアーティファクトの削除を混同しないでください。既存のクライアントはメタデータをキャッシュしている可能性があり、すでに問題のあるバージョンを実行している場合もあります。ロールバックプランには、以前の署名済みリリース、フィードの変更、および復旧可能なクライアントの挙動が必要です。
運用ルール: インシデント発生時、オンコールエンジニアはアプリケーションを再ビルドすることなく、ロールバックを実行できなければなりません。
実務上のランブックでは、以前のリリースマニフェストを対象のチャネルに昇格させ、ステージングマーカーを無効化し、新しいチェックが安全なバージョンに解決されることを確認する必要があります。問題がネイティブシェルではなく、レンダラーの code にある場合は、Webレイヤーに絞ったロールバックの方が迅速な場合があります。例えば、 Capgo の段階的なロールアウト のようなプラットフォームは、その個別の配信レイヤーにおいて有効ですが、ネイティブバイナリのロールバックとWebバンドルのロールバックの境界を曖昧にすべきではありません。
Auto-Updateをセキュリティコントロールとして扱う
Electronのアップデーターは実行可能な code をダウンロードし、ユーザーの操作をほとんど介さずにインストールできます。そのため、アップデートパスは単なる利便性のための機能ではなく、 セキュリティ境界として捉える必要があります。Electronの公式ドキュメントにはmacOS ATSなどのプラットフォームの制約が記載されており、セキュリティに関する調査では、アップデートインフラを制御する攻撃者が、code の署名チェックを通過する悪意のあるパッケージを配信できた2022年のシナリオも報告されています。詳細は、 Electron Builderのauto-updateセキュリティドキュメント を参照してください。.
Code の署名は基本ですが、それだけで信頼モデルが完結するわけではありません。すべてのリリースに署名を行い、CI プロセス中に証明書と ID を検証し、文書化された鍵のローテーション手順を維持してください。macOS では、署名に加えて、アプリケーションに適した Notarization と Hardened Runtime を組み合わせてください。Windows では、証明書の所有権、更新、およびビルドへのアクセス権を監査可能にします。Linux は、Electron に汎用的なアップデーターが組み込まれていないため、ディストリビューションごとの戦略が必要です。
バイナリと同様にメタデータも保護する
メタデータのチャネルが侵害されたり設定ミスがあったりすると、署名済みバイナリであっても誤ったリリースに関連付けられる可能性があります。アプリケーションに埋め込まれた公開鍵で検証するマニフェスト署名の追加、許可される最小バージョンの強制、および許可されたリカバリパスによる明示的な許可がない限り予期しないダウングレードを拒否することを検討してください。
フィードにも本番環境レベルの制御が必要です:
- 公開アクセスの制限: CI には、リリース資産の公開に必要な権限のみを付与してください。
- 署名シークレットの保護: 証明書や秘密鍵はリポジトリ内のファイルではなく、管理されたシークレットストレージに保管してください。
- 依存関係の固定: CI において Electron、electron-builder、および間接的な依存関係をロックしてください。
- アーティファクトのレビュー: 生成されたパッケージをスキャンし、意図したコミットおよびバージョンと比較してください。
- セキュアな通信の必須化: アップデートのリクエストには、ATSおよび厳格なHTTPS要件に従ってください。
- 検証失敗の監視: 署名やマニフェストの検証失敗が繰り返される場合は、単なるネットワークノイズではなく、セキュリティイベントとして扱ってください。
Electronの整備されたツールエコシステムにより、パッケージングやアップデーターの対応範囲は拡大し続けていますが、メンテナンスが進んでも脅威モデリングの必要性がなくなるわけではありません。実用的な目的は、バケット、CDN、またはビルドステップが侵害されたとしても、攻撃者が不正なリリースをクライアントに受理させることができないようにすることです。 署名検証のガイドライン は、追加の検証レイヤーを設計するための有用なコンテキストを提供します。

プロダクションアップデートのランブックとチェックリスト
リリースが「準備完了」と言えるのは、他のエンジニアがプレッシャーのかかる状況下でも操作できる状態になった時だけです。チェックリストはデプロイ作業やインシデント用チャンネルの近くに置いておきましょう。
リリース前のゲート
- バージョンの識別: パッケージのバージョン、リリースタグ、コミットSHA、および変更履歴が一致していることを確認します。
- 署名: すべてのプラットフォームのアーティファクトが署名され、Notarization(または同等の検証)が完了していることを確認します。
- マニフェストの整合性: 確認事項:
latest.yml,latest-mac.ymlハッシュ、パス、およびブロックマップがアップロードされたアーティファクトと一致していること。 - チャネルの安全性: リリースチャネルを昇格させる前に、内部またはベータフィードに公開してください。
- テレメトリ: アップデートの確認、ダウンロードの進捗、インストールの完了、起動時のヘルスチェック、およびエラーが正しく送信されていることを確認します。
カナリアリリースとフルロールアウト
- コホート制御: まずは、意図的に規模を絞った社内ユーザーやベータ版ユーザーから開始しましょう。
- ヘルスバジェット: リリース失敗、アップデートのダウンロード失敗、レンダラー例外、または認証エラーがチームの承認済み制限を超えた場合は、プロモーションを停止してください。
- プロモーションの承認: リリースを安定版フィードに移行する前に、明示的なGo/No-Goの判断を必須とします。
- 顧客への影響: サポート用のメッセージは、最初のインシデントが発生した後ではなく、広範囲に配布する前に準備しておきましょう。
インシデント対応
新しいバイナリの起動失敗、プロセス生成の破損、またはアップデートのダウンロードが完了しない場合は、直ちにプロモーションを停止してください。以前の署名済みマニフェストを復元し、ステージングマーカーを無効化して、新しいクライアントが以前のバージョンに解決されることを確認します。その後、テレメトリを通じて全デバイスが復旧していることを確認してから、対応完了を報告してください。
正確なロールバックコマンドはプロバイダーによって異なりますが、手順は常にドキュメント化しておくべきです。 チャンネルのマニフェストを前のバージョンに切り替え、ステージングタグを無効化し、必要に応じて強制アップデートマーカーをプッシュし、ライブテレメトリでダウングレードパスを確認します。テストされていないロールバックは、単なる「願い」に過ぎません。

Capgo は、レンダラーの変更のたびに Native Build をやり直すことなく、署名済みの Web レイヤーの変更、ターゲットチャンネル、ロールアウト制御、およびアップデートのオブザーバビリティを実現する Electron アップデーターを提供します。ネイティブバイナリのリリースと、制御された JavaScript および CSS の配信を分離したい場合は、こちらをご覧ください: Capgo 既存の Electron リリースパイプラインと比較して検討してください。