Contents

Github Actions rebuild native dependencies 會卡住問題

我最近做 Electron 專案有用到 native dependency,在 GitHub Actions 建構時卡在 rebuild native dependencies,畫面看起來像還在跑,但其實放再久也不會自己好,最後直接被 GitHub 的時間上限砍掉。

這個問題通常出在哪

Electron 專案只要碰到 native module,像是 win32 API、sqlite、serialport 這類套件,electron-builder 在打包時常常會試著幫你做 rebuild。理論上這是為了讓 native 模組和 Electron 的執行環境相容,但在 CI 上有時候會:

  1. 卡在 node-gyp。
  2. 找不到對應編譯工具鏈。
  3. 重複 rebuild 已經裝好的 dependency。
  4. 只顯示執行中,實際上沒有任何進度。

如果你是在本機可以正常包,只有 GitHub Actions 卡住,這個方向就很值得先查。

我遇到的症狀

我這邊是 workflow 跑到一半就停住,Action 看起來沒失敗,但也不往下走。原本以為只是 CI 機器慢,結果放了幾小時還是一樣,最後超過 6 小時被 GitHub 自動中止。

這種狀況最麻煩的地方是 log 不一定很明顯,所以如果你看到流程一直停在 native dependencies rebuild 附近,不要太相信它只是慢。

解法

我後來參考這篇 issue,先把 electron-builder 的自動 rebuild 關掉:

Electron-builder keeps rebuilding native dependency · Issue #5386 · electron-userland/electron-builder

關鍵設定:

1
2
3
4
5
{
	"build": {
		"npmRebuild": false
	}
}

有些文件會寫成字串,但我自己會直接用布林值 false,可讀性也比較清楚。

https://i.imgur.com/ziHqxBb.png

放在哪裡

通常可以放在:

  1. package.json 的 build 區段。
  2. electron-builder 的獨立設定檔。

如果你是 package.json 設定,大概會像這樣:

1
2
3
4
5
6
7
{
	"name": "your-app",
	"build": {
		"appId": "com.example.app",
		"npmRebuild": false
	}
}

這樣做的代價

這個解法很實用,但不是完全沒代價。因為你關掉 rebuild 之後,前提變成:你的 native dependency 在前面的 install 流程就要已經是正確且可用的。

所以我覺得比較安全的做法是:

  1. 先確認 lock file 是穩定的。
  2. 確認 CI 使用的 Node.js 版本固定。
  3. 確認 native 套件本身支援目前 Electron 版本。

如果這三件事沒先穩住,就算關掉 rebuild,有時只是把問題延後到執行階段才爆。

我的結論

如果 GitHub Actions 剛好卡在 rebuild native dependencies,而你本機打包正常,先試 npmRebuild: false 是很合理的第一步。這至少可以快速判斷卡點是不是 electron-builder 的 rebuild 流程,而不是整個專案真的編不過。

我這邊加完之後,GitHub Actions 就能順利往下跑。之後如果要更穩,再回頭整理 native 套件版本和 CI 環境會比較扎實。