Skip to content

chore: dev→main 同期(CI リトライ+release-build ワークフローを本番化)#64

Open
sasagar wants to merge 2 commits into
mainfrom
dev
Open

chore: dev→main 同期(CI リトライ+release-build ワークフローを本番化)#64
sasagar wants to merge 2 commits into
mainfrom
dev

Conversation

@sasagar

@sasagar sasagar commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

v0.4.0 以降の ci: 変更(#62 CIリトライ・#63 release-build ワークフロー)を main へ。ユーザー向け feat/fix は無いので release-please はバージョンを上げない(=タグは増えない)。目的は release-build ワークフローを main で有効化し、次回リリースを .app 自動添付+Cask 自動 bump にすること。

sasagar added 2 commits July 5, 2026 13:36
* fix: 孫プロセスがパイプを握ると ProcessRunner がハングするデッドロックを解消

ProcessRunner.runSync は stdout/stderr を readDataToEndOfFile() で EOF まで読むが、
子プロセスが即終了しても**孫プロセスがパイプの write 端を継承したまま生き残る**と EOF が
来ず、drain.wait() が永久にハングする。CI($SHELL -l がログイン profile でバックグラウンド
常駐を起動する環境)で ToolLocator の不在ツール検索が login shell を起こし、swift test が
無限に止まる原因だった(アプリ実行時の ToolDoctor でも同様にハングし得る実バグ)。

修正:
- DataBox.fill を read(upToCount:) ループに変更(別スレッドから close で中断可能に)。
- runSync は子の終了後、drain が有限時間(2s)で終わらなければ read ハンドルを閉じて
  強制的に解き、読めた分だけを返す(timeout 判定は従来どおり)。

回帰テスト testDoesNotHangWhenGrandchildKeepsPipeOpen を追加(sh が echo 後に sleep を
バックグラウンド起動して stdout を握る=以前はハング、修正後は ~2s で有限に戻る)。
ローカル: swift test 89/89 パス。

* test/ci: ログインシェル起動テストを CI では skip+swift test に timeout 保険

真のハング要因は ToolLocatorTests.testLocateAbsentToolReturnsNil:有効名は許可リストを
通り locateViaLoginShell($SHELL -l -c command -v)まで到達する。CI ランナーによっては
ログイン profile がバックグラウンド常駐を起こし、孫がパイプを握って ProcessRunner が
ハング → swift test が無限停止。単体テストで実ログインシェルを起こすのは非ハーメティック
なので CI では XCTSkipIf でスキップ(ローカルは実行して回帰維持)。

あわせて ci.yml の swift test に timeout-minutes: 12 を追加(万一のハングを 6h ではなく
短時間で fail させる保険)。ProcessRunner のパイプ・デッドロック修正は実行時ハングの
恒久対策として維持(defense in depth)。

* ci: swift test をリトライ方式にして稀なランナー・ハングを吸収

CI ログ解析で、swift test は稀にビルド/テスト段階で無限ハングする(xctest プロセスが
生き残る/出力はブロックバッファで flush されず原因テスト名が特定できない)ことが判明。
ローカル(macOS 26)では再現せず、CI(macos-15)固有のフレーク。ProcessRunner の
close-during-read 修正は FileHandle の未定義動作でランナーによっては逆にデッドロックし得る
ため revert し、代わりに原因非依存で堅牢な対策を採る:

- swift test を各試行 7 分のウォッチドッグ付きで最大 3 回リトライ(健全な実行は ~2-3 分)。
  ハングした試行は kill して次の(別)ランナー相当で再実行。
- ジョブ全体 timeout-minutes: 25 を保険に。
- ToolLocatorTests の login shell 起動テストは CI で skip(非ハーメティック回避・維持)。

ローカル swift test 88/88 パス。
release-please がリリースを publish(タグ作成)したら macos ランナーで Release ビルド →
アドホック署名 → zip → そのリリースへ添付する。手動実行(workflow_dispatch)で既存タグへの
後追いビルドも可能。HOMEBREW_TAP_TOKEN(Love-Rox/homebrew-tap への write PAT)を設定すると
Cask の version/sha256 を自動更新(未設定なら ::notice の sha256 で手動更新)。

配布はアドホック署名(無料・notarization なし)。ローカルで Release ビルドが自己完結の
universal .app(x86_64+arm64、libghostty/GRDB 静的リンク)として起動することを検証済み。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant