Tauri Static Updater JSONはsignatureの中身を見る
Tauriのstatic updater JSONは小さいファイルですが、小さいからといって失敗しにくいわけではありません。
一番多い間違いは、JSONにsignature fileのpathを書くことです。Tauriが欲しいのは.sigファイルへのpathではありません。生成された.sigファイルの中身です。
updaterがreleaseを見つけない、manifestを拒否する、downloadしない、という時は、updater codeを変える前にJSON fieldを確認します。
症状: updaterがreleaseを見つけない、またはmanifestを拒否する
アプリは次のように振る舞うことがあります。
- update checkは完了するがupdateが表示されない
- manifest errorやsignature errorが出る
- mock serverやCDNは
latest.jsonを正常に返している - installer fileは存在する
- それでもアプリがupdateをinstallしない
これはupdater pluginが壊れているという意味ではありません。static JSON manifestには厳密なfieldがあり、1つの値が違うだけでupdateは止まります。
static updater JSONの必須keyを使う
最小のstatic manifestには、versionとplatform entryが必要です。
{
"version": "1.0.1",
"notes": "Bug fixes and small improvements.",
"pub_date": "2026-07-03T12:00:00Z",
"platforms": {
"windows-x86_64": {
"signature": "SIGNATURE FILE CONTENT",
"url": "https://releases.my-app.invalid/my-app_1.0.1_x64-setup.exe"
}
}
}
optional fieldは便利ですが、updaterが最低限必要とするのは次です。
versionplatforms.<target>.urlplatforms.<target>.signature
platform keyはupdaterが確認するtargetと一致している必要があります。通常の64-bit Windows buildなら、多くの場合windows-x86_64です。
.sig pathやURLではなく、中身を貼る
これは間違いです。
{
"signature": "my-app_1.0.1_x64-setup.exe.sig"
}
これも間違いです。
{
"signature": "https://releases.my-app.invalid/my-app_1.0.1_x64-setup.exe.sig"
}
updaterが期待しているのはsignature fileの中身です。
{
"signature": "untrusted comment: signature from minisign secret key\nRWQ..."
}
manifestを生成するときは、.sigファイルを読み、末尾の空白をtrimします。
const fs = require("node:fs");
const signature = fs
.readFileSync("dist/my-app_1.0.1_x64-setup.exe.sig", "utf8")
.trim();
その文字列をJSONへ書き込みます。
platform keyと生成artifactを合わせる
JSONのplatform keyは人間向けのlabelではありません。updaterがassetを選ぶためのkeyです。
manifestにこれしかない場合:
{
"platforms": {
"linux-x86_64": {
"signature": "SIGNATURE",
"url": "https://releases.my-app.invalid/my-app.AppImage"
}
}
}
Windows appはこのentryを使いません。
multi-platform releaseでは、列挙したplatform entryをすべて完全にします。Tauriはmanifest全体をvalidateするため、現在のmachineがinstallしないplatformでも、壊れたentryがfile全体をinvalidにすることがあります。
署名済みbuildのたびにmanifestを再生成する
.sigファイルを固定metadataのように扱わないでください。
release processはこうします。
1. updater artifactをbuildする
2. .sig fileが存在することを確認する
3. そのartifactと.sig fileからlatest.jsonを生成する
4. artifactとlatest.jsonを一緒にuploadする
5. upload済みfileに対してtest updateを行う
避けるべき順番はこれです。
1. latest.jsonを手で編集する
2. installerをrebuildする
3. 古いsignature stringを再利用する
4. まとめてuploadする
manifestは前回releaseからcopyするのではなく、build outputから生成します。
download debugの前にversion ruleを見る
manifestがvalidなのにアプリがno updateを返す場合は、versionを比べます。
static manifestのversionは、アプリがinstallすべきversionである必要があります。installed appがすでに1.0.1で、manifestも1.0.1なら、通常のupdater checkは新しいupdateとして扱いません。
local testでは、古いversionを先にinstallし、mock serverから高いversionを返します。
installed app: 1.0.0
manifest version: 1.0.1
1.0.1に対して1.0.1をtestしているなら、それはno-update pathのtestです。
小さなmanifest generatorを使う
手編集より、早く失敗するscriptのほうが安全です。
const fs = require("node:fs");
const version = process.argv[2];
const url = process.argv[3];
const sigFile = process.argv[4];
if (!version || !url || !sigFile) {
throw new Error("Usage: node make-updater-json.js <version> <url> <sig-file>");
}
if (!fs.existsSync(sigFile)) {
throw new Error(`Signature file not found: ${sigFile}`);
}
const manifest = {
version,
notes: `Release ${version}`,
pub_date: new Date().toISOString(),
platforms: {
"windows-x86_64": {
signature: fs.readFileSync(sigFile, "utf8").trim(),
url
}
}
};
fs.writeFileSync("latest.json", JSON.stringify(manifest, null, 2));
これで、signature file不足と古い手編集JSONという2つの大きなミスを防げます。
参考
まとめ
Tauri static updater manifestが失敗したら、コードを書き換える前にdataを確認します。signatureはfile content、platform keyはtargetと一致、URLは実artifact、manifestは正確な署名済みbuildから再生成、という順で切り分けます。