Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
8a10e2e
feat: 差分アップデートを追加
sevenc-nanashi Jul 5, 2025
c316767
feat: wip
sevenc-nanashi Jul 6, 2025
b871001
feat: とりあえず動いた
sevenc-nanashi Jul 6, 2025
42768ac
chore: ダウンロードをアプデ画面に映す
sevenc-nanashi Jul 7, 2025
d87d436
feat: アップデートボタンを追加
sevenc-nanashi Jul 7, 2025
66dc391
feat: ダウンロードのダイアログを表示
sevenc-nanashi Jul 7, 2025
4c54143
chore: 細かいところを消す
sevenc-nanashi Jul 7, 2025
655a72f
style: eslintの怒られを修正
sevenc-nanashi Jul 7, 2025
cafc5ca
chore: スナップショットを更新
sevenc-nanashi Jul 7, 2025
4ce246c
(スナップショットを更新)
github-actions[bot] Jul 7, 2025
6164b65
fix: ダークテーマのボタンを修正
sevenc-nanashi Jul 7, 2025
1b5fddb
(スナップショットを更新)
github-actions[bot] Jul 7, 2025
7f749ee
feat: huggingfaceにアップロードするように
sevenc-nanashi Jul 7, 2025
e6a412f
fix: ifを移動
sevenc-nanashi Jul 7, 2025
58e2451
fix: ifを移動
sevenc-nanashi Jul 7, 2025
58c10e6
chore: windows-2019からwindows-2022に移行 (#2700)
sevenc-nanashi Jul 5, 2025
1c683b0
fix: ifの条件を修正
sevenc-nanashi Jul 7, 2025
63c43bd
fix: typo修正
sevenc-nanashi Jul 7, 2025
8369deb
chore: DOWNLOAD_BASE_URLにversionを追加
sevenc-nanashi Jul 8, 2025
16394e5
fix: versionをURLにつける
sevenc-nanashi Jul 8, 2025
b69bb9e
chore: yml指定にする
sevenc-nanashi Jul 8, 2025
9911ffc
chore: prepackageを消す
sevenc-nanashi Jul 8, 2025
3d2abb5
fix: INSTALLER_ARTIFACT_NAMEにする
sevenc-nanashi Jul 8, 2025
d30d896
fix: version欄を治す
sevenc-nanashi Jul 8, 2025
e5ef5fe
fix: iniを動かす
sevenc-nanashi Jul 8, 2025
2036dc8
fix: voicevox -> voicevox-test
sevenc-nanashi Jul 8, 2025
1d21dc6
fix: voicevox -> voicevox-test
sevenc-nanashi Jul 8, 2025
30fec5c
fix: update_infosを差し替える
sevenc-nanashi Jul 8, 2025
cd95804
fix: app-updateが欠けているので治す
sevenc-nanashi Jul 8, 2025
b651811
fix: urlを修正
sevenc-nanashi Jul 8, 2025
2ff2d3d
chore: zip版でのエラーを追加
sevenc-nanashi Jul 8, 2025
fe2ac52
chore: テキストを修正
sevenc-nanashi Jul 8, 2025
dc8dde5
chore: iniをcopyにする
sevenc-nanashi Jul 8, 2025
57571e9
Merge: upstream/main -> poc/diff-updater
sevenc-nanashi Jul 9, 2025
915364a
chore: いったんmacosのアプデをあきらめる
sevenc-nanashi Jul 11, 2025
3f2515f
feat: ダウンロードのプログレス表示を追加
sevenc-nanashi Jul 11, 2025
3474cbb
style: nr lint:fix
sevenc-nanashi Jul 11, 2025
d9d448e
chore: progressをまとめる
sevenc-nanashi Jul 12, 2025
d52003d
chore: コメントを増やす
sevenc-nanashi Jul 12, 2025
a3dcde1
chore: アップデートできないときはボタンを無効化する
sevenc-nanashi Jul 12, 2025
de599b7
feat: Storyを足す
sevenc-nanashi Jul 12, 2025
abb37fa
(スナップショットを更新)
github-actions[bot] Jul 12, 2025
e2b1ddd
chore: prereleaseでもhfに上げるようにする
sevenc-nanashi Jul 12, 2025
3274b2d
Merge: upstream/main -> poc/diff-updater
sevenc-nanashi Jul 12, 2025
8b03f99
merge: upstream/main -> poc/diff-updater
sevenc-nanashi Jul 13, 2025
7624268
style: node protocolをつける
sevenc-nanashi Jul 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.production
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VITE_APP_NAME=voicevox
VITE_APP_NAME=voicevox-test
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メモ:戻す

Copy link
Member

@Hiroshiba Hiroshiba Jul 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(ここに関係ないけど、議論分けたいのでここにコメントしました)

ちょっと相談です!!
かなりシステムが複雑化するのでどう進めようか迷っています。
例えばサーバーサイドのコードもこのリポジトリで管理するとか、projectブランチ作ってわりと途中な状態でもマージしやすくするとかを考えてます。

あるいは抜本的な解決策として、先にエンジン分離をやってしまえば、差分アプデがすごく簡単になる(githubのみで完結する)ことを思いつきました。
なので差分アプデを作り込んだときの恩恵は一時的でよく、そのためにサーバーを建てるのはかなり遠回りかもとか思いました。
huggingfaceとgithubのみで完結する形か、あるいは先にエンジン分離をやってしまうのはどうでしょうか…?

現状まだ考えきれてないですが、サーバー追加周りは考えることが山ほどあるなと思ってます。
例えばapi変更するときどうするのとか、セキュリティ的なのどうするのとか、ドキュメント書かないととか、ドメイン取らないととか、dev用サーバーどう建てようとか、単一情報源の法則どうしようとか(=blogへの依存を増やすのか)…。
あとはmacだけ解決してない(ダウンロード数見るにユーザー全体の2割くらいがmac)とかも考慮ポイントかも。

まああとで考えれば良いことが多いですが、であればもうエンジン分離してしまった方が早いんじゃないかと、ふと思ったのでコメントしてみました…。
自分の中でも結論でておらず、どうすべきかかなり悩んでいますが、サーバーを追加する場合サクッと実装するのが難しいのではと気づき始めていて、先にエンジン分離するのが丸いのかもと思い始めています🙇
以前と言ってること違ってたりしたらご指摘いただければ!!🙇

VITE_DEFAULT_ENGINE_INFOS=`[
{
"uuid": "074fc39e-678b-4c13-8916-ffca8d505d1d",
Expand Down
75 changes: 44 additions & 31 deletions build/funcs.nsh
Original file line number Diff line number Diff line change
Expand Up @@ -39,38 +39,45 @@
Push $0 ; Stack $0
Push $1 ; $1 $0

; electron-builder のスクリプトに基づいたハッシュ値と対象ファイル名の取得
; https://github.com/electron-userland/electron-builder/blob/28cb86bdcb6dd0b10e75a69ccd34ece6cca1d204/packages/app-builder-lib/templates/nsis/include/installer.nsh#L17-L70
!ifdef APP_64_NAME
!ifdef APP_32_NAME
!ifdef APP_ARM64_NAME
${if} ${IsNativeARM64}
StrCpy $0 "${APP_ARM64_NAME}"
StrCpy $1 "${APP_ARM64_HASH}"
${elseif} ${IsNativeAMD64}
StrCpy $0 "${APP_64_NAME}"
StrCpy $1 "${APP_64_HASH}"
${else}
StrCpy $0 "${APP_32_NAME}"
StrCpy $1 "${APP_32_HASH}"
${endif}
${StdUtils.GetParameter} $0 "package-file" ""
; 引数でパッケージのパスが指定されている場合はそれを優先する(electron-updater用)
${If} $0 != ""
; ハッシュチェックは省略する(electron-updater がすでに行っているため)
StrCpy $1 "__DANGEROUS_SKIP_HASH_CHECK__"
${Else}
; electron-builder のスクリプトに基づいたハッシュ値と対象ファイル名の取得
; https://github.com/electron-userland/electron-builder/blob/28cb86bdcb6dd0b10e75a69ccd34ece6cca1d204/packages/app-builder-lib/templates/nsis/include/installer.nsh#L17-L70
!ifdef APP_64_NAME
!ifdef APP_32_NAME
!ifdef APP_ARM64_NAME
${if} ${IsNativeARM64}
StrCpy $0 "${APP_ARM64_NAME}"
StrCpy $1 "${APP_ARM64_HASH}"
${elseif} ${IsNativeAMD64}
StrCpy $0 "${APP_64_NAME}"
StrCpy $1 "${APP_64_HASH}"
${else}
StrCpy $0 "${APP_32_NAME}"
StrCpy $1 "${APP_32_HASH}"
${endif}
!else
${if} ${RunningX64}
StrCpy $0 "${APP_64_NAME}"
StrCpy $1 "${APP_64_HASH}"
${else}
StrCpy $0 "${APP_32_NAME}"
StrCpy $1 "${APP_32_HASH}"
${endif}
!endif
!else
${if} ${RunningX64}
StrCpy $0 "${APP_64_NAME}"
StrCpy $1 "${APP_64_HASH}"
${else}
StrCpy $0 "${APP_32_NAME}"
StrCpy $1 "${APP_32_HASH}"
${endif}
StrCpy $0 "${APP_64_NAME}"
StrCpy $1 "${APP_64_HASH}"
!endif
!else
StrCpy $0 "${APP_64_NAME}"
StrCpy $1 "${APP_64_HASH}"
StrCpy $0 "${APP_32_NAME}"
StrCpy $1 "${APP_32_HASH}"
!endif
!else
StrCpy $0 "${APP_32_NAME}"
StrCpy $1 "${APP_32_HASH}"
!endif
${EndIf}

; Stack $1 $0
Exch $1 ; <ResultHash> $0
Expand Down Expand Up @@ -225,11 +232,17 @@
Exch 2 ; <Hash> $1 $0
Exch $2 ; $2 $1 $0

${StdUtils.HashFile} $0 "$1" "$0"
${If} $0 == $2
${If} $2 == "__DANGEROUS_SKIP_HASH_CHECK__"
; ハッシュチェックをスキップする。
; electron-updater などの、すでにハッシュが検証済みのものを使う場合にのみ使用すること。
StrCpy $0 "OK"
${Else}
StrCpy $0 "Failed"
${StdUtils.HashFile} $0 "$1" "$0"
${If} $0 == $2
StrCpy $0 "OK"
${Else}
StrCpy $0 "Failed"
${EndIf}
${EndIf}

; Stack $2 $1 $0
Expand Down
43 changes: 13 additions & 30 deletions build/installer.nsh
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,17 @@ verifyPartedFile_finish${UniqueID}:
!macro verifyArchive Result
Push $0 ; Stack $0
Push $1 ; $1 $0
Push $2 ; $2 $1 $0

${StdUtils.ValidPathSpec} $2 $archiveName
${If} $2 == "ok"
; アーカイブ名が有効なパスであるならそのまま使う
StrCpy $0 $archiveName
${Else}
; そうでないなら $EXEDIR からフルパスを作成する
StrCpy $0 "$EXEDIR\$archiveName"
${EndIf}

StrCpy $0 "$EXEDIR\$archiveName"
${IfNot} ${FileExists} $0
StrCpy $0 "File not found"
${Else}
Expand All @@ -315,7 +324,8 @@ verifyPartedFile_finish${UniqueID}:
${EndIf}
${EndIf}

; Stack $1 $0
; Stack $2 $1 $0
Pop $2 ; $1 $0
Pop $1 ; $0
Exch $0 ; <Result>
Pop "${Result}" ; -empty-
Expand Down Expand Up @@ -485,6 +495,7 @@ verifyPartedFile_finish${UniqueID}:
; 正しいハッシュ値を持った 7z ファイルがあるか検証する
${verifyArchive} $0
${EndIf}

${If} $0 == "OK"

StrCpy $additionalProcess "None"
Expand Down Expand Up @@ -770,34 +781,6 @@ Function readyPageLeave
${EndIf}
readyPageLeave_finish:
FunctionEnd

; README を表示するためのオプションを流用して、
; セットアップ完了画面にファイル削除のチェックボックスを追加する
Function deleteArchive
Delete "$EXEDIR\$archiveName"
FunctionEnd
!define MUI_FINISHPAGE_SHOWREADME
!define MUI_FINISHPAGE_SHOWREADME_TEXT "使い終わったダウンロード済みファイルを削除する"
!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
!define MUI_FINISHPAGE_SHOWREADME_FUNCTION deleteArchive

!macroend

!macro customHeader
; インストール成功後に%LOCALAPPDATA%\voicevox-updater\を削除する
Function .onInstSuccess
; https://github.com/electron-userland/electron-builder/blob/f717e0ea67cec7c5c298889efee7df724838491a/packages/app-builder-lib/templates/nsis/include/installer.nsh#L77
${if} $installMode == "all"
SetShellVarContext current
${endif}
Push $R0
${GetParent} "$LOCALAPPDATA\${APP_PACKAGE_STORE_FILE}" $R0
RMDir /r "$R0"
Pop $R0
${if} $installMode == "all"
SetShellVarContext all
${endif}
FunctionEnd
!macroend

; "%VITE_APP_NAME%"が空の状態でビルドすると他のソフトのファイルを消してしまうためビルドエラーにする。
Expand Down
4 changes: 4 additions & 0 deletions dev-app-update.yml
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メモ:消す

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これも消す感じですかね

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ですね。

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
provider: generic
url: http://localhost:3000
useMultipleRangeRequest: false
updaterCacheDirName: voicevox-updater
6 changes: 3 additions & 3 deletions electron-builder.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,9 @@ const builderOptions = {
allowToChangeInstallationDirectory: true,
},
publish: {
provider: "github",
repo: "voicevox",
vPrefixedTagName: false,
provider: "generic",
url: "http://localhost:3000",
useMultipleRangeRequest: false,
},
linux: {
artifactName: LINUX_ARTIFACT_NAME !== "" ? LINUX_ARTIFACT_NAME : undefined,
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "voicevox",
"version": "999.999.999",
"name": "voicevox-test",
"version": "0.24.8",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

メモ:戻す

"author": "Hiroshiba Kazuyuki",
"private": true,
"main": "./dist/main.js",
Expand Down Expand Up @@ -59,6 +59,7 @@
"async-lock": "1.4.1",
"dayjs": "1.11.13",
"electron-log": "5.4.1",
"electron-updater": "6.6.2",
"electron-window-state": "5.0.3",
"encoding-japanese": "2.2.0",
"fast-array-diff": "1.1.0",
Expand Down
35 changes: 35 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/backend/browser/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,4 +244,7 @@ export const api: Sandbox = {
getPathForFile(/* file: File */) {
throw new Error(`Not supported on Browser version: getPathForFile`);
},
updateApp(/* version: string */) {
throw new Error(`Not supported on Browser version: updateApp`);
},
};
5 changes: 5 additions & 0 deletions src/backend/electron/ipcMainHandle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { IpcMainHandle } from "./ipc";
import { getEngineInfoManager } from "./manager/engineInfoManager";
import { getEngineProcessManager } from "./manager/engineProcessManager";
import { getWindowManager } from "./manager/windowManager";
import { getUpdateManager } from "./manager/updateManager";
import { AssetTextFileNames } from "@/type/staticResources";
import { failure, success } from "@/type/result";
import {
Expand Down Expand Up @@ -354,5 +355,9 @@ export function getIpcMainHandle(params: {
return failure(a.code, a);
}
},

UPDATE_APP: async (_, obj) => {
await getUpdateManager().updateApp(obj.version);
},
};
}
3 changes: 0 additions & 3 deletions src/backend/electron/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
"use strict";

import path from "path";

import fs from "fs";
import { pathToFileURL } from "url";
import { app, dialog, Menu, net, protocol, shell } from "electron";
Expand Down
55 changes: 55 additions & 0 deletions src/backend/electron/manager/updateManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { autoUpdater as electronUpdater } from "electron-updater";
import { DisplayableError } from "@/helpers/errorHelper";
import { createLogger } from "@/helpers/log";

const log = createLogger("AutoUpdateManager");

// ログの設定
electronUpdater.logger = createLogger("electron-updater");
// 手動でアップデートをダウンロードするために自動ダウンロードを無効化
electronUpdater.autoDownload = false;
// アプリ終了時に自動的にインストールする挙動を無効化
electronUpdater.autoInstallOnAppQuit = false;
// 開発版でもアップデートを有効化する
electronUpdater.forceDevUpdateConfig = true;

electronUpdater.on("error", (error) => {
log.error("AutoUpdater error:", error);
});

electronUpdater.on("update-downloaded", (info) => {
log.info("Update downloaded:", info);
});

export class UpdateManager {
constructor() {}
async updateApp(version: string) {
const latest = await electronUpdater.checkForUpdates();
if (latest == null || latest.updateInfo == null) {
log.error("Assertion failed: Latest update info is null");
throw new DisplayableError(
`アップデートサーバーからの情報が取得できませんでした。時間をおいてからもう一度やり直してください。`,
);
}
if (latest.updateInfo.version !== version) {
log.error(
`Assertion failed: Server's latest: ${latest?.updateInfo.version}, Current: ${version}`,
);
throw new DisplayableError(
`アップデートサーバーのバージョンが現在のバージョンと異なります。時間をおいてからもう一度やり直してください。`,
);
}

await electronUpdater.downloadUpdate();
log.info("Quitting and installing update...");
electronUpdater.quitAndInstall();
}
}

let managerInstance: UpdateManager | null = null;
export function getUpdateManager(): UpdateManager {
if (managerInstance == null) {
managerInstance = new UpdateManager();
}
return managerInstance;
}
4 changes: 4 additions & 0 deletions src/backend/electron/renderer/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ const api: Sandbox = {
getPathForFile: async (file) => {
return webUtils.getPathForFile(file);
},

updateApp: async (obj) => {
return await ipcRendererInvokeProxy.UPDATE_APP(obj);
},
};

const wrapApi = (baseApi: Sandbox): SandboxWithTransferableResult => {
Expand Down
Loading
Loading