リリースチャンネル分岐の第 3 段階: 取得と自動置き換え - #48
Conversation
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0d91937afd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codex レビュー (#48) の指摘への対応。 - 退避した .old と staged の後始末を、起動シーケンスの先頭からウィンドウ 構築後へ移す。先頭で消すと、置き換え直後の起動が初期化の途中で失敗した 場合に復旧の材料を両方失う。先頭の照合は破棄なし (discardMismatches: false) で行う - 適用に失敗して巻き戻した場合、ヘルパは staged を捨てて現行版を起動し 直す。残すと次の起動がまた同じ適用へ引き渡し、書き込めない場所に置かれた 環境では現行版すら開けなくなる - 入れ替え前の検証で app / cli の実行ファイルの存在も見る。digest は ZIP が 配布物そのものであることまでしか保証しない - 取得に打ち切り (30 分 + 破棄時のキャンセル) を渡す。本文の読み取りは HttpClient のタイムアウトの外にあり、止まった取得が取得の直列化を 持ち続けると以後の取得がすべてスキップされる - ヘルパの終了待ちを 10 分へ延ばす。終了時の同期は大きな DB で数分かかり うる。待ちきれない場合は staged を残し、次の起動で適用し直す Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149RhLaw1THcTkR6i5f6xLC
新しい版の ZIP を常駐中に取得して SHA-256 と大きさを照合し、 %AppData%\VRCToolsDataSync\update に置き換え待ちとして保管する (issue #45 第 3 段階)。置き換えは次の起動の先頭で行う。 実行中の App は app\ 配下の DLL を掴んでいて自分では置き換えられないため、 展開した新しい一式の cli を更新ヘルパ (self-update apply) として起動し、 App の終了を待ってから app / cli をリネームで入れ替えてもらう。重い複製を 先に済ませて正規の位置に触るのは短いリネームだけにし、失敗したら退避した .old を戻す。戻せなかった状態は別の例外と終了コードで区別する。 適用の直前と次の起動では、チャンネル適合・実行中との版の前後・記録との 照合をやり直し、通らないものはその場で捨てる。画面には取得済みの行と 「再起動して適用」ボタンを足した。 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149RhLaw1THcTkR6i5f6xLC
チャンネルの選び方、確認と通知のタイミング、取得と照合、次の起動での 置き換えの仕組み、手元ビルドが対象外であることを書く。 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149RhLaw1THcTkR6i5f6xLC
第 3 段階で IReleaseRepository へ取得を足したとき、確認のテストの偽物へ 実装を足し忘れてビルドが落ちていた。確認の判断だけを見るテストであり 取得へは到達しないため、呼ばれない実装として埋める。 Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149RhLaw1THcTkR6i5f6xLC
Codex レビュー (#48) の指摘への対応。 - 退避した .old と staged の後始末を、起動シーケンスの先頭からウィンドウ 構築後へ移す。先頭で消すと、置き換え直後の起動が初期化の途中で失敗した 場合に復旧の材料を両方失う。先頭の照合は破棄なし (discardMismatches: false) で行う - 適用に失敗して巻き戻した場合、ヘルパは staged を捨てて現行版を起動し 直す。残すと次の起動がまた同じ適用へ引き渡し、書き込めない場所に置かれた 環境では現行版すら開けなくなる - 入れ替え前の検証で app / cli の実行ファイルの存在も見る。digest は ZIP が 配布物そのものであることまでしか保証しない - 取得に打ち切り (30 分 + 破棄時のキャンセル) を渡す。本文の読み取りは HttpClient のタイムアウトの外にあり、止まった取得が取得の直列化を 持ち続けると以後の取得がすべてスキップされる - ヘルパの終了待ちを 10 分へ延ばす。終了時の同期は大きな DB で数分かかり うる。待ちきれない場合は staged を残し、次の起動で適用し直す Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149RhLaw1THcTkR6i5f6xLC
85dfa75 to
086524d
Compare
…uto-apply-tezzcs # Conflicts: # src/VRCToolsDataSync.App/ViewModels/MainPageViewModel.cs
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 96f851ffd8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codex レビュー (#48) の指摘への対応。 - 取得は一時の場所 (incoming.zip) へ書き、照合が通ってから置き換え待ちの 対へ昇格させる。正規の場所へ直接書くと、取得済みの版がある状態で次の 取得が途中で失敗したときに、適用できたはずの前の版まで失う - 取得を省く判定でタグだけでなく digest と大きさも見る。同じタグへ配布物を 上げ直す運用 (release.yml の --clobber) があり、タグだけで済ませると 差し替え前のものを適用し続ける - 入れ替えの最中のログを best-effort にする。ログの出力先が書き込み不可だと ロガーが例外を投げ、巻き戻しを通らずに抜けて、新しい app と古い cli が 混ざった一式が残る - 後始末を UpdateManager 経由にして、済んだことを画面へ伝える。直接呼ぶと 適用の済んだ取得が消えたことが伝わらず、「次回起動時に適用されます」の 行が押すまで残る Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149RhLaw1THcTkR6i5f6xLC
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1e5ad1283e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codex レビュー (#48) の追加指摘への対応。 - 取得した配布物の名前を記録へ残し、適用の前に実行中のプロセスと突き合わせる。 ARM64 の Windows ではネイティブの版とエミュレーションの x64 版が同じ 置き場所を共有しうる。名前を持たない古い記録も適用しない - ランチャーは同じディレクトリの一時ファイルへ書き切ってから置き換える。 直接上書きすると、書いている途中で容量が尽きた場合に欠けたランチャーが 残り、通常の起動手段ごと壊れる - 適用に失敗したときの再起動は、取得済みのものを消せた場合だけにする。 消せないまま開き直すと、次の起動がまた同じ適用へ入って失敗し、開いては 閉じるのを繰り返す。消せない場合は片付ける先を伝えて終える (終了コード 8) - 適用をクロスプロセスのロックで囲う。ヘルパは適用の全体で握り、App は 起動の先頭から展開とヘルパ起動まで握る。これが無いと、ヘルパの実行中に 起動された App が同じ展開先を作り直し、動いているヘルパの足元を崩す Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149RhLaw1THcTkR6i5f6xLC
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 25ac076158
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codex レビュー (#48) の追加指摘への対応。 - 記録へ取得時のインストール先を残し、適用の前に突き合わせる。配布 ZIP を 複数の場所へ展開していると、どのコピーも同じ置き場所を共有する。合わない ものはここでは捨てない (相手のコピーが適用できるように) - 取得した ZIP の昇格を、適用と同じロックの下で行う。昇格は staged の ZIP を 入れ替えて展開先を消すため、適用と重なると起動前のヘルパを消したり、 動いているヘルパの展開元を欠いたりする - ヘルパの流れの上にあるログを best-effort にする。入れ替えの後にログが 例外を投げると、staged の破棄にも App の起動し直しにも辿り着かず、 「再起動して適用」がアプリを閉じるだけになる Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149RhLaw1THcTkR6i5f6xLC
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 30e61a9923
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
「再起動して適用」で、取得済みの照合をロックの外で行っていた。照合と展開の 間に裏の取得が別の ZIP を昇格させると、確かめたものとは違う版が展開される。 照合・インストール先の判定・ヘルパ起動を一つのロック区間にまとめた。 置き場所も分ける。複数の場所へ展開したコピーが update\ を共有すると、 一方が取った更新を他方が「取得済み」と見て取得を省く一方、インストール先が 違うので適用はできず、相手が片付けるまで更新できない行き止まりに入る。 インストール先のハッシュで 1 段掘って分けた。 使われなくなった TrySpawnUpdaterWithLock を削除した。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0149RhLaw1THcTkR6i5f6xLC
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 52ef6728cc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
予約された装置名 (CON / LPT1、CON.dll のような形も含む) と使えない文字 (? * | " < > :・制御文字) を含む項目名を、展開の前に断るようにした。これらは Windows ではその名前のファイルを作れないため、ExtractToDirectory が途中で IOException を投げる。従来はその失敗を捨てる判断に使えず、取得済みの ZIP が 残り続けて起動のたびに同じ失敗を繰り返していた。 あわせて、名前の規則を 1 つずつ数え上げる形から抜けられるようにした。展開の 前に空き容量を確かめ、足りなければ IOException で断って取得は残す。その先の 展開で落ちた場合は、容量以外の理由、つまり Windows で作れない形の配布物と みなして InvalidDataException にそろえる。呼び出し側はこれを見て取得ごと 捨てるので、同じ ZIP での失敗が繰り返されない。
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0df9e6cf99
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
前の変更で、空き容量を確かめた後の展開の失敗をすべて配布物の問題として 扱ったが、それではウイルス対策ソフトが一瞬掴んだ場合や、確認の後に空きが 尽きた場合にも、正しい ZIP を捨てて数百 MB の取り直しを強いる。例外の種類 では一時的なものと見分けられないため、同じ ZIP で何回失敗したかを数える形へ 変えた。2 回目までは投げ直して取得を残し、3 回目で配布物の問題として扱う。 数は昇格 (新しい ZIP) と展開の成功で 0 に戻す。数は照合に使う対とは別の ファイルに置き、書きかけで落ちても対に触らないようにしている。 あわせて 2 点。 - 非圧縮の大きさの合計を、足す前に上限と突き合わせるようにした。項目の 大きさは ZIP の目録の値をそのまま受け取るので、桁を偽られると足し算が 折り返し、負の合計として上限も空き容量の確認もすり抜ける - インストール先の空き容量を、複製に入る前に確かめるようにした。複製の 途中で尽きると、ヘルパはそれを置き換えの失敗として扱い、取得しておいた ZIP まで捨ててしまう。UpdateCapacityException で分け、ヘルパは取得を 残したまま現行版を開き直す (終了コード 9)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fc39eb9a0e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
空き不足で置き換えを断念したヘルパは、取得しておいたものを残したまま App を 開き直す。しかし開き直された App は起動シーケンスの先頭で同じ取得を見つけ、 またヘルパへ渡す。ヘルパはまた同じ空き不足で断念して開き直す。利用者が外から 空きを作るか取得を消すまで、この往復が続く。 App に見送りの指定 (--skip-update-apply) を渡せるようにし、容量不足の経路だけ これを付けて開き直すようにした。指定つきで起動された App はその回だけ適用へ 入らず、そのまま立ち上がる。取得は残るので、空きができた後の起動で適用し直す。
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2dc8461eff
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
3 点。 - 昇格の最後の付け替え (記録を正規の名前へ置く) だけが失敗した場合、新しい ZIP は正規の場所に居るのに記録が無い形で止まり、次の起動の片付けが片方だけ の状態として ZIP まで捨てていた。横に残っている記録を置き直してから捨てる 判断に入るようにした。置き直した対が食い違っていれば、その後の照合が digest と大きさで気付いて捨てる - 更新ヘルパが、置き換えの間だけ App の多重起動の抑止も掴むようにした。掴んで いないと、入れ替えの最中に起動した App が旧 app\ を読み込んで掴み、入れ替え を失敗させたり、置き換え済みの一式をもう一度置き換えさせて退避した旧版を 上書きさせたりする。呼び出し元とは別の App が既に動いている場合は、正規の 位置に触らずに引き下がる (待つと、あちらが適用のロックを待っている場合に 噛み合わない)。App を起動し直す前には必ず手放す - 同じ場所がファイルとディレクトリの両方になる ZIP (app/foo と app/foo/bar.dll など) を展開の前に断るようにした。名前としては重なっていないので項目名の 突き合わせでは通るが、展開すれば必ず失敗する。一時的な失敗と見分けられず、 数回の空振りを経てから捨てられていた
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f02ccec337
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
2 点。 - 昇格で古い記録を消していたため、その後の ZIP の入れ替えに失敗すると、正規の 場所に前の ZIP だけが残り、適用できたはずの前の版まで失っていた。消さずに 横へ退避し、入れ替えに失敗したら戻すようにした。戻せなかった場合は次の起動の 片付けが拾う (新しい記録があれば仕上げ、退避した古い記録しか無ければ戻す) - インストール先の空きを測る前に、前回の失敗が残した .new を消すようにした。 PrepareAndSwap も複製の前に消すが、測る時点では残っているため、消せば足りる 状況でも容量不足として断り続けていた
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a3c49bdada
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
展開の空き容量の確認が、前回の展開先が残ったままの空きを見ていた。インストール 先が別ドライブにある場合、そちらの容量不足で staged を残して終わったヘルパが 完成済みの展開先を残すため、次の適用では残骸の分だけ空きが足りないと判断され、 その先の削除に到達しないまま繰り返す。削除を EnsureExtractable より前へ移した。 なお incoming.zip は測る対象から外していない。取得中のものかもしれず、消すと 走っている取得を壊すためである。
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7cc926ff8e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
4 点。 - 昇格の途中で止まった状態の復旧を、記録の名前ではなく ZIP との照合で決める ようにした。「古い記録を退避する → ZIP を入れ替える」の間で電源が落ちると、 ZIP は前のままで横に新旧 2 つの記録が並ぶ。新しいほうを名前で選ぶと合わない 対になり、両方捨てられていた - ZIP の項目数と項目名の総量に上限を置いた。中身が空の項目は展開後の大きさに 現れないため、数で押し切られると突き合わせ用の集合と展開先の両方を使い切る。 自動適用は画面を出す前に走るので、そうなると App が開かなくなる - 更新チャンネルを読めない場合に stable として扱っていたため、後始末の突き合わせ で test の取得がチャンネル外と判定され、正しい取得を捨てていた。「読めない」を 区別し、その場合は突き合わせ自体を見送る (次の起動が拾う) - ヘルパが呼び出し元の終了を待ちきれずに降りた場合、App はそのまま終わるため、 利用者から見ると「再起動して適用」で画面が閉じたきりになっていた。終了の 直前にヘルパの生死を見て、居なければ抑止とロックを手放してから開き直す
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 19eafb629b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
3 点。 - 昇格の仕上げが「読めない・動かせない」で終わった場合も、そのまま片方だけの 状態として ZIP を捨てていた。仕上げの結果を「不要 / 済んだ / 分からない」で 返し、分からない場合はその回の片付けを中止する。記録の読み出しも、壊れている (捨ててよい) と読めない (次へ回す) を投げ分ける - インストール先の空きを測る前に、前回の置き換えが残した .old も消すようにした。 .new と同じく PrepareAndSwap が次に消す対象で、数に入れたまま測ると、消せば 足りる状況でも断り続ける。現行版のそろいは先に確かめており、複製に失敗しても 現行版は無傷なので、この時点で消してよい - ヘルパへ渡した後は設定の保存を受け付けないようにした。ヘルパは渡した時点の チャンネルで照合を済ませているため、終了時 Push を待つ間に stable へ変えて 保存されると、保存済みの設定と適用される版が食い違う。終了が取り消された場合 (ヘルパも止めている) は受け付け直す
|
@codex review 前回のレビュー(
Generated by Claude Code |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a61fd8c83c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
3 点。 - 前回が残した .new / .old を消せない場合、正規の位置に触っていないのに一般の 失敗として扱われ、ヘルパが取得済みの ZIP まで捨てていた。空き不足と同じ 「見送り」に倒す。空き不足の UpdateCapacityException を UpdateDeferredException の下へ移し、ヘルパは基底のほうで捕まえる - 設定の保存を止める時点を、ヘルパを起こした後から適用の準備に入る時点へ early に移した。準備にはヘルパの生存確認の 3 秒が含まれ、その間も画面は 操作できるため、渡した後に保存される窓が残っていた。準備に失敗した場合は 下ろす - 取得を省いてよいかを、記録どおりかではなく ZIP との照合で決めるようにした。 常駐中に ZIP だけが壊れた場合、記録だけを見て省くと次の起動でそれが捨てられ、 適用にもう一度の再起動が要る。確認は 24 時間に 1 度なので、ここで数百 MB を 読む負担は許容する。読めなかった場合は省く側に倒す (掴まれているだけのこと があり、そこで取り直させない)
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 561af120ac
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
3 点。 - 更新ヘルパがログの置き場所を作れない場合に、その場で落ちていた。親の App は 「起きてすぐ落ちたヘルパ = 壊れた配布物」と見なして取得を捨てるため、ログを 書けないことの代償が数百 MB の取り直しになる。ログ無しで続行するようにした - ディレクトリの後始末を「あるか見てから消す」から「消しに行って、無かった だけを成功として分ける」に変えた。Directory.Exists は権限や一時的な失敗でも false を返すため、消せていないものを消せたことにして先へ進み、正規の位置で 失敗して取得まで捨てていた。展開先を消せない場合も、展開の失敗と同じ数え方に 乗せる (何度やっても消せないなら、取得を持ち続けても適用できない) - 展開の失敗の数に、記録の digest を添えるようにした。数を消し損ねた場合や昇格の 直後に落ちた場合、新しい ZIP が前の ZIP の回数を引き継ぎ、1 度つまずいただけで 捨てられていた
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: be206c1eb3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // どの ZIP の回数かを、記録の digest で見分ける。数を消す側が失敗した場合や、 | ||
| // 昇格の直後に落ちた場合、前の ZIP の回数がそのまま残る。それを引き継ぐと、 | ||
| // 新しい ZIP が 1 度つまずいただけで捨てられる。 | ||
| var generation = TryLoadMetadata()?.DigestHex ?? string.Empty; |
There was a problem hiding this comment.
前回指摘後に追加された世代分けでも、展開失敗時に staged.json が一時的に読めないと TryLoadMetadata() が null を返し、すべての ZIP が空文字の同一世代として数えられます。前の ZIP で空文字世代の失敗数が 2 まで残り、昇格時に extract-failures を削除できなかった場合、新しい正常な ZIP はメタデータ読み取りと展開が一度だけ同時に失敗しただけで 3 回目と判定され、InvalidDataException 経由で破棄されます。世代は既に検証済みのメタデータから渡すなど、取得不能時に共有値へフォールバックしないでください。
AGENTS.md reference: AGENTS.md:L3-L5
Useful? React with 👍 / 👎.
|
|
||
| try | ||
| { | ||
| Move(current, backup); |
There was a problem hiding this comment.
更新ヘルパがこの移動を終えた直後から .new を正規名へ移すまでに電源断や強制終了が起きると、app は存在せず app.old と app.new だけが残ります。例外処理による巻き戻しはプロセス終了時には走らず、ランチャーも app\VRCToolsDataSync.App.exe を直接起動するだけなので、次回起動で更新を再開するコードへ到達できず、利用者が手作業でディレクトリを戻すまで App を起動できません。ランチャーまたは別の常駐しない起動経路で中断状態を検出し、正規名が欠けていれば .old を復元できるようにしてください。
AGENTS.md reference: AGENTS.md:L3-L5
Useful? React with 👍 / 👎.
| { | ||
| var fresh = Path.Combine(_targetDirectory, part + ".new"); | ||
| ClearLeftover(fresh); | ||
| CopyDirectory(Path.Combine(_sourceDirectory, part), fresh); |
There was a problem hiding this comment.
複製中の一時的な I/O 失敗でも staged を保持してください
ウイルス対策ソフトが展開元のファイルや作成中の app.new/cli.new を一時的に保持すると、この複製は IOException または UnauthorizedAccessException を投げます。この時点では正規の app と cli にまだ触れていませんが、例外は UpdateDeferredException に変換されず CLI の一般失敗処理へ届くため、正常な staged ZIP とメタデータまで破棄されます。作りかけの .new を片付けた後、残骸削除の失敗と同じ見送りとして伝え、ロックが外れた次回に同じ取得を再利用してください。
AGENTS.md reference: AGENTS.md:L3-L5
Useful? React with 👍 / 👎.
issue #45 の第 3 段階(取得と自動置き換え)。第 1 段階 #46 と第 2 段階 #47 はマージ済みで、base は
master。KxNotifyUtils の installer.cr の「常駐中は取得と検証まで、置き換えは次の起動」という分担を踏襲しつつ、単一 exe ではなく ZIP 配布(
app/+cli/+ ランチャー)に合わせて置き換えの実行主体を変えている。実行中の App はapp\配下の DLL を掴んでいて自分では置き換えられないため、取得した ZIP の中の CLI を更新ヘルパとして起動し、App の終了を待ってからディレクトリを入れ替えてもらう。ヘルパは展開先から動くので、置き換える対象のどれも掴まない。変更内容
Core
GitHubReleaseRepository.DownloadAsync: ZIP を取得しながら SHA-256 と宣言された大きさを照合する。宣言を超えた時点で打ち切り、照合を通らなければファイルを残さない。応答ヘッダまでを既定のタイムアウトで待ち、本体の読み取りは呼び出し側から渡された期限(App の寿命 + 30 分)に委ねる(数十〜百数十 MB を想定)UpdateStage: 取得した ZIP と記録(tag / digest / size / 配布物の名前 / 取得元のインストール先 / stable の印)の置き場所。置き場所は%AppData%\VRCToolsDataSync\update\<インストール先のハッシュ>とインストール先ごとに分ける(同じ ZIP を複数の場所へ展開したコピー同士が互いの取得を奪い合わないため)incoming.zipへ書き、照合を通ってから置き換え待ちの対へ昇格させる。昇格は「新しい記録を横へ書く → 古い記録を横へ退避する → ZIP を入れ替える → 新しい記録を置く」の順。正規の場所に触る前に落ちれば前の対が無傷で残り、ZIP の入れ替えに失敗した場合も退避した記録を戻す。最後の付け替えは短く待ってやり直す.・..・末尾の点と空白をそろえて突き合わせる)。同じ場所がファイルとディレクトリの両方になる組み合わせ、展開先の外を指す項目、Windows では作れない名前(予約された装置名・使えない文字)も断る。展開後の大きさ・項目数・項目名の総量にも上限を置き、大きさの合計は足す前に突き合わせる(目録の値で折り返させないため)UpdateInstaller:app/cliの入れ替え。重い複製(.newの用意)を先に済ませ、正規の位置に触るのは短いリネームだけにする。複製が途中で失敗したら作りかけを消す。正規の位置に触る前に、app/cliのディレクトリ・実行ファイル・本体アセンブリの存在を確かめ、前回が残した.new/.oldを消してからインストール先のドライブの空きを確かめる(空き不足はUpdateCapacityExceptionで分け、取得を捨てさせない)。失敗したら退避した.oldを戻し、戻せなかった状態はUpdateRollbackExceptionで区別する。ランチャーは.cmd.newへ書き切ってから置き換える。入れ替え中のログはすべて best-effort(ログの失敗が巻き戻しを飛ばさない)。FindInstallRootは配布 ZIP の形(<ルート>\app\+ ランチャー)だけを認め、手元ビルドの作業ツリーを誤って置き換えないRunningVersion.OfFile: 動いていない一式に埋め込まれた版を読む。適用の前に、展開したapp/cliが記録のタグどおりの版かを確かめるのに使うCli
self-update apply --source --target --wait-pid --wait-started --relaunch(ヘルプ非表示)。起動直後に適用のロックの待ちへ入り(呼び出し元が終わる時点で待ち行列に居るため、放棄されたロックを受け取れる)、取れたら呼び出し元の終了を確かめ、App の多重起動の抑止も掴んでからUpdateInstallerで入れ替え、App を起動し直す。抑止も掴むのは、入れ替えの最中に起動した App が旧app\を掴んで入れ替えを失敗させたり、置き換え済みの一式をもう一度置き換えさせたりするため(既に別の App が動いていれば、正規の位置に触らずに引き下がる)。呼び出し元は番号だけでなく開始時刻でも見分ける(番号の使い回しで無関係なプロセスを待たないため)。巻き戻し済みの失敗では staged を捨ててから現行版を起動し直し、同じ失敗を繰り返さない。巻き戻し失敗は終了コード 7、staged の対が残ってしまった場合は 8、インストール先の空き不足は 9 で区別する(9 では staged を残したまま現行版を開き直す。開き直す際は見送りの指定--skip-update-applyを渡し、その App がまた同じ取得を渡してくる往復を避ける。空きを作れば次の起動がそのまま適用する)。App
Global\VRCToolsDataSync.Update.Apply.<インストール先のハッシュ>。Global\なのは、接頭辞が無いと対話セッションごとの名前空間に作られ、置き場所とインストール先は共有されるのにロックだけが互いに見えなくなるため。専用の背景スレッドが所有し、外からは合図だけで手放せる(Mutexの所有権はスレッドに紐づくため)app\を掴んだままヘルパの入れ替えに巻き込まれたりする-Versionを渡し忘れたビルドが添付されると、適用と再起動を繰り返して復旧の材料まで失う).oldと不要になった取得の片付けは、ウィンドウを立てられた後(CleanUpAfterSuccessfulStart)に行う。新版が初期化の途中で失敗しても、旧版と取得済み ZIP の両方が復旧の材料として残る。後始末は取得と同じ入り口を通し、返した後に待たせていた取得を拾う。チャンネルを読めない場合は突き合わせ自体を見送る(stable として見ると test の取得を捨てる)UpdateManager: 確認で見つけた版に配布物が付いていれば常駐中に自動取得する(通知を抑止した版も対象。抑えたのは繰り返しの通知であって取得ではない)。取得は 1 本ずつで、走っている間に来た要求は置いておき、終わった側が拾う。取得の前・昇格の前・適用ロックを取った後に保存済みのチャンネルと突き合わせ、確認の最中に切り替えられた場合は追随する。取得を省くのはタグ・digest・大きさ・stable の印がすべて一致する場合だけREADME
自動アップデートの節を追加。リリース節の書き換え(第 1 段階分)は #46 へ入れた。
検証
FindInstallRootの判定)、埋め込まれた版の読み出し。入れ替えは実ディレクトリで確かめている設計上の判断(レビューで見てほしい点)
app\とcli\はリネームで入れ替え、ランチャー.cmdは 1 ファイル置き換え。ランチャーの置き換え失敗は警告に留める(旧ランチャーでも相対参照で新しい app を起動できる)積み残し
_downloadGate)がプロセス内にしか効かず、incoming.zipを共有する。多重起動の抑止と設定の保存も同じ前提で共有されており(どちらも リリースチャンネルの分岐と自動アップデート機能を実装する #45 以前からこの形)、名前空間をどう揃えるかは機能をまたぐ判断になるため別立てにした。単一セッションでの利用には影響しない.oldを戻す形を別立てにした。現状でも.oldは残るので手で復旧はできる🤖 Generated with Claude Code
https://claude.ai/code/session_0149RhLaw1THcTkR6i5f6xLC
Generated by Claude Code