GitHub Actions ubuntu-latest 要換 Ubuntu 26.04?遷移檢查清單
GitHub Actions 的 ubuntu-latest 不是永遠指向同一個 Ubuntu 版本。Ubuntu 26.04 已經提供 x64 與 Arm hosted runner,GitHub 也宣布 ubuntu-latest 會在 2026 年 10 月 19 日至 11 月 19 日逐步由 Ubuntu 24.04 移到 Ubuntu 26.04。
直接答案是:先用明確的 ubuntu-26.04 建立非阻斷測試矩陣,再決定是否讓工作流程跟隨 ubuntu-latest;尚未驗證相容性時,暫時釘選 ubuntu-24.04。 不要等到 label 自動切換後,才從失敗的 production release 追查是哪個預裝工具或作業系統行為變了。
本文整理的是遷移流程與檢查方法。這次排程沒有替任何 repository 執行 GitHub Actions,也沒有在實際 release pipeline 驗證結果;版本與可用 label 以你執行 workflow 時的 GitHub runner 文件和 image readme 為準。
先看這次遷移會改變什麼
Ubuntu 26.04 runner 已正式提供下列常用 label:
| 用途 | Label | 適合怎麼用 |
|---|---|---|
| x64 新版測試 | ubuntu-26.04 | 先跑相容性矩陣,確認套件與工具 |
| x64 穩定回復 | ubuntu-24.04 | 尚未完成遷移時暫時釘選 |
| 跟隨 GitHub 預設 | ubuntu-latest | 遷移後持續取得 GitHub 的 latest image |
| Arm 新版測試 | ubuntu-26.04-arm | 驗證原生 Arm runner 與第三方 action |
這些 label 只告訴你 runner image 的選擇,不保證所有預裝工具都與舊 image 相同。Ubuntu 26.04 的 image readme 會列出作業系統和工具清單,但你的 workflow 仍應該把真正需要的 Node.js、Python、Java、瀏覽器或 CLI 版本明確安裝,而不是依賴「剛好預裝」。
1. 先盤點 workflow 的 runner 與隱藏依賴
在 repository 根目錄搜尋所有 runs-on,包含 reusable workflow 和 matrix:
rg -n --glob '.github/workflows/**' \ 'runs-on:|ubuntu-latest|ubuntu-[0-9]{2}\.[0-9]{2}|arm' .接著把每條 job 的依賴記下來:
- 是否直接使用
ubuntu-latest,或由${{ matrix.os }}間接指定。 - 是否安裝依賴於 Ubuntu image 的 system package、OpenSSL、Python、Java 或 Docker 行為。
- 是否使用只提供 x64 binary 的 action、CLI 或 native Node module。
- cache key、artifact 名稱或測試結果是否混用了不同 OS/架構。
- release、deploy、migration job 是否有 production 權限,不能直接拿來做第一次測試。
若 workflow 很多,可以先列出 label 而不改檔案:
rg -n --no-heading --glob '.github/workflows/**' 'runs-on:' .這一步的價值是找出「表面上只有一個 latest,實際上被多個 release job 共用」的情況。先分辨測試、建置與部署責任,後面的釘選策略才不會把所有工作流程一起凍結。
2. 用非阻斷矩陣測試 Ubuntu 26.04
先讓同一組測試同時跑舊版與新版,並把新版 job 設成不阻斷主流程。等結果穩定後,再移除 continue-on-error 或改變主要 label:
jobs: test: strategy: fail-fast: false matrix: os: [ubuntu-24.04, ubuntu-26.04] runs-on: ${{ matrix.os }} continue-on-error: ${{ matrix.os == 'ubuntu-26.04' }} steps: - uses: actions/checkout@v5 - uses: actions/setup-node@v6 with: node-version-file: .nvmrc cache: npm - run: npm ci - run: npm test這個範例只示範遷移矩陣;actions/checkout、actions/setup-node 的版本和 cache 設定仍要依你的 repository policy 管理。若沒有 .nvmrc,請改成明確的 runtime 版本,避免 OS 遷移與 Node 升級同時發生而難以定位。
比較結果時,不要只看 job 綠不綠。至少保留兩邊的:
- 安裝與 lockfile 錯誤。
- native module 編譯輸出。
- lint、型別檢查和測試失敗的第一個堆疊。
- artifact、cache hit rate 和產出檔案的差異。
- deploy 前的 dry run 或設定檔驗證結果。
3. 在 job 內記錄實際的版本
同一個 major 版本也可能因 image 更新而有不同 patch 版本。針對會影響產出的工具,在測試階段先輸出版本,讓失敗可以和 image 變更對照:
- name: Record runner environment run: | cat /etc/os-release uname -a node --version || true npm --version || true python3 --version || true java -version || true docker --version || true正式 job 不需要無條件安裝所有語言;原則是「凡是會改變編譯或測試結果的工具,都應該由 workflow 明確指定版本」。GitHub runner image 只應提供底層環境,不能當成 lockfile。
如果你依賴 image 預裝的 CLI,至少把 image readme 的查核日期和 CLI 版本納入 migration note。更穩定的方式是使用官方 setup action、容器或專案自己的 toolchain,並在 cache key 中納入 OS 與架構:
- uses: actions/cache@v4 with: path: ~/.cache/my-tool key: ${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/lockfile') }}這個 cache key 只是示意;實際 cache 路徑、action 版本和 lockfile 名稱要依專案調整。重點是不要讓 Ubuntu 24.04 與 26.04、x64 與 Arm 共用一份不相容的 native cache。
4. 需要時暫時釘選 ubuntu-24.04
如果新版測試還有阻斷問題,可以把 production job 從 ubuntu-latest 改為 ubuntu-24.04,並建立明確的再評估日期:
jobs: release: runs-on: ubuntu-24.04釘選不是永久解法。你仍要:
- 在 issue 或 migration checklist 記錄阻斷原因、負責人和回測條件。
- 確認第三方 action、native dependency 和 Docker base image 的支援範圍。
- 把
ubuntu-26.04測試保留在 pull request 或 nightly workflow。 - 在下一個 image/runtime 版本更新前重新檢查,而不是無限延後。
不要把 ubuntu-24.04 當成「完全不會變」的承諾;它只是目前可用的明確版本 label。未來若要移到其他 image,仍應重跑同一套盤點與矩陣驗證。
5. 另外驗證 Arm runner
ubuntu-26.04-arm 不是把 x64 job 的 label 貼上去就完成。Arm 測試至少要確認:
- 使用的 Docker image 是否有 multi-architecture manifest。
- npm、Python 或其他依賴中的 native module 是否有 Arm wheel/binary,或能在 runner 上編譯。
- 第三方 action 是否支援目前架構,尤其是包裝 CLI 的 action。
- cache 與 artifact 是否把
runner.arch納入識別。 - 測試資料、timeout 與 parallelism 是否因硬體差異需要調整。
如果 production 仍是 x64,不必為了追求 label 對稱而把所有 deploy job 改成 Arm;先把 Arm 當成明確的相容性測試目標。
遷移完成前的檢查清單
可以在 pull request 描述中逐項勾選:
- 所有
runs-on來源都已找到,包含 reusable workflow 和 matrix。 - 以
ubuntu-26.04跑過測試,並保存失敗輸出與工具版本。 -
ubuntu-latest與ubuntu-24.04的差異已被分類,不把偶發失敗直接歸因於 OS。 - 重要 runtime、CLI、瀏覽器與 native dependency 已明確指定。
- cache、artifact 和測試結果不會跨 OS/架構誤用。
- release/deploy job 有單獨的核准與回復策略。
- 若暫時釘選
ubuntu-24.04,已留下再評估日期和負責人。 - 若使用 Arm,已確認 image、action 和 native dependency 的架構支援。
常見問題
Q: ubuntu-latest 會在 2026 年 10 月 19 日當天全部切換嗎?
A: 不會。GitHub 公告的遷移窗口是 2026 年 10 月 19 日至 11 月 19 日,會逐步進行。不要用單一日期假設所有 workflow 同時改變,應在窗口前完成明確 label 的測試。
Q: 已經使用 ubuntu-latest,為什麼還要測 ubuntu-26.04?
A: 因為 latest 是移動中的別名。直接測明確 label 可以把新 image 的差異提前暴露,也能在尚未準備好時暫時釘選舊版,降低 release 被動切換的風險。
Q: 只要 build 通過,就代表遷移完成嗎?
A: 不代表。還要檢查測試、cache、artifact、部署 dry run、第三方 action 與架構差異。這次排程只完成文章與本地站台建置,沒有執行你的 GitHub Actions 或 production deployment。
參考資料:
GitHub Changelog:Ubuntu 26 generally available and latest migration
回報錯字、失效連結,或告訴我你想看的延伸主題。