知識與實務

商業實務・AI 應用・人才發展

AI 工作實務

GitHub Actions CI 實作:讓 Node.js PR 跑真測試,驗證錯誤變更會讓測試失敗

CI 的綠燈只能代表已設定的檢查通過;如果測試不會發現錯誤,跑得再頻繁也沒有保護作用。本篇用完整 Node.js 專案建立 PR 工作流,加入邊界測試與故意失敗的驗證,再說明如何把執行結果接到合併規則。

CI 從程式碼、檢查到測試結果的流程

CI 的綠燈只能代表已設定的檢查通過;如果測試不會發現錯誤,跑得再頻繁也沒有保護作用。本篇用完整 Node.js 專案建立 PR 工作流,加入邊界測試與故意失敗的驗證,再說明如何把執行結果接到合併規則。

專題編輯:Derek Chou|AI 技術與架構編輯 · 文件核對 2026.11.09

CI 從程式碼、檢查到測試結果的流程

把綠色勾勾翻譯成具體證據

同一個功能由 AI 協助修改後,開發者本機可以執行,並不代表合併進主線也安全。其他人的修改可能改變 API 欄位、依賴或測試資料;修改累積越久,出錯時越難判斷原因。CI 的實務重點,是讓小幅變更經常接受共同驗證,縮短發現整合問題的時間。GitHub CI 說明

本文把範圍縮成一個可重現的問題:報價金額「超過」100,000 元才需額外檢查,若程式被改成「大於或等於」,CI 能不能抓到?這是一個教學規則,不是實際公司政策。你會取得程式、測試與工作流三種檔案,並學會分辨「測試通過」「測試有偵錯能力」及「儲存庫確實禁止合併」三個狀態。

完整發布治理可延伸閱讀CI/CD 發布回執與回滾檢查。本文聚焦在 Node.js PR 的具體測試工作流;正式部署、灰度發布與回滾不在這個範例內。

先準備能被 CI 執行的專案

下載完整範例專案並解壓。你需要有 GitHub 儲存庫寫入及開啟 Actions 的適當權限;設定合併規則則另需相應管理權限。工作流會使用 GitHub 託管 runner,是否產生費用、可用額度與功能限制依帳號方案及組織政策而定,本文未查閱你的帳務。

範例以 .nvmrc 記錄 Node.js 22.23.4,沒有第三方 npm 依賴。2026 年 11 月 9 日本機以 macOS、Node.js 22.23.4、npm 10.9.9 通過測試。雲端執行的 runner、Node/npm 版本與結果應另看該次 Actions 紀錄,不能以本機成功替代。

專案布局如下,保留開頭為點號的目錄與檔案:

.github/workflows/ci.yml
.nvmrc
package.json
package-lock.json
src/quote.js
src/server.js
test/quote.test.js
scripts/verify-gate.js

程式檔定義輸入及結果;測試檔把要求寫成會失敗的判斷;工作流只負責在指定事件發生時執行這些命令。這三層各自可讀,審查者才能知道綠燈的範圍。

步驟一:先在本機確認五個測試真的存在

進入範例根目錄,執行:

node --version
npm --version
npm ci --ignore-scripts --no-audit --no-fund
npm test

預期測試總數為 5、失敗數為 0。它們涵蓋低於門檻、恰好等於門檻、超過一元,以及無效金額。只檢查成功結束碼不夠;測試數變成零、重要案例被 skip,都需要追查原因。

最關鍵的兩個測試相鄰但意義不同:

test('threshold itself needs no extra review', () => {
  assert.equal(reviewAmount(100000).reviewRequired, false);
});
test('one dollar above threshold needs review', () => {
  assert.equal(reviewAmount(100001).reviewRequired, true);
});

若只有 50,000 元和 200,000 元兩個案例,> 被改成 >= 仍可能完全沒被發現。這是測試設計問題,不是多跑幾次 CI 能修復的問題。AI 產生測試後,也應把案例和需求的邊界逐一對照。

步驟二:新增不持有部署權限的工作流

將範例內容放入專用測試儲存庫的根目錄;若採用既有 monorepo,需另調整 working-directory、node-version-file 與 cache-dependency-path,不要直接把其他專案設定覆蓋掉。工作流如下:

name: Quote contract CI
on:
  pull_request:
  push:
    branches: [main]
permissions:
  contents: read
jobs:
  verify:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - uses: actions/checkout@v7
        with:
          persist-credentials: false
      - uses: actions/setup-node@v7
        with:
          node-version-file: .nvmrc
          cache: npm
      - name: Record tool versions
        run: |
          node --version
          npm --version
      - run: npm ci --ignore-scripts --no-audit --no-fund
      - run: npm test
      - run: npm run verify:gate

pull_request 負責 PR 變動時的檢查,push 則核對 main 上的提交;兩者都不包含部署命令。contents: read 限制這個工作流的 repository token 權限,範例不需要資料庫密碼、WordPress 憑證或雲端部署金鑰。工作流語法、GITHUB_TOKEN 權限

這裡使用當次官方 README 示範的 v7 系列;它是 Action 的版本,不是要測試的 Node 版本。組織若要求更嚴格供應鏈控制,應核對官方 release 後固定完整 commit SHA,並維護更新流程,不要從不明教學複製一個看似完整的 SHA。setup-node 官方文件

快取可縮短下載時間,但不能省略 npm ci 或測試。setup-node 的 npm 快取也不等於保留整個 node_modules;本範例依 lockfile 安裝,才執行實際案例。安裝命令的 --no-audit 表示此工作流未承諾漏洞稽核。

步驟三:讓正常變更通過,也讓錯誤變更留下失敗證據

先建立一個分支與 PR,確認 Actions 有觸發,而不是只看到 YAML 檔已上傳。檢查紀錄中的提交、Node/npm 版本、npm ci、5 個測試及負例工具。若工作流沒有啟動,先核對 Actions 是否允許執行、事件與分支是否符合,以及檔案是否真的在 .github/workflows/ 下。

npm run verify:gate 在臨時副本把 amount > 100000 改成 amount >= 100000,再呼叫真正的 Node 測試執行器。工具只有觀察到非零結束碼,才回報「錯誤邊界被拒絕」;結束後移除臨時副本。這個步驟證明測試對指定錯誤有反應,正常原始碼仍應保持全綠。

要驗證 PR 的狀態真的會變紅,可在專用演練分支直接改壞這個運算子並提交。預期 npm test 失敗,後續成功門檻不成立;接著把該分支的單一變更修正,再確認新提交恢復通過。不要在正式產品或未備份的工作分支做這種演練。

這裡要記錄兩個不同層級:負例工具在本機已驗證;PR 的紅燈/綠燈必須以實際 Actions run 為準。不能因為工具自行印出 PASS,就宣稱 GitHub 的合併限制已生效。

步驟四:把檢查接到主線合併規則

CI 執行失敗,並不自動等於沒有人可以合併。擁有管理權限者需依儲存庫方案及組織政策設定 Ruleset 或分支保護,選擇適用分支,要求 PR 及必要的狀態檢查,再確認規則已啟用。GitHub Rulesets 說明

設定時使用實際 run 顯示的檢查名稱,避免只靠猜測。例如日後改了 job 名稱,原有 required check 可能不再對應。設定完成後,以有代表性的演練 PR確認:未跑、失敗、成功三種狀態各自能否合併,並核對哪些角色具有 bypass 權限。

本文沒有修改任何讀者儲存庫的保護規則,也沒有替管理員宣稱權限驗收通過。有效的驗收紀錄應保存規則範圍與演練結果;若需要管理權限而目前沒有,就把這一步列為待管理員完成,不透過另建高權限 token 迴避。

CI 故障時,先看哪個訊號?

訊號優先調查不宜採用的快速掩蓋方式
npm ci 失敗鎖版檔、依賴差異、安裝選項換成 install 讓它自行改鎖版
本機成功,runner 失敗Node/npm、OS、大小寫、環境變數給 runner 全部正式機密
測試偶爾失敗時序、共享資料、網路依賴無限重跑直到偶然成功
重要檢查沒有產生事件、路徑條件、job 名稱直接移除 required check
測試全綠但仍出錯未覆蓋的輸入及整合邊界用 coverage 百分比當完整保證

範例專案不編譯,因此沒有空的 build 步驟;實際 TypeScript、前端或跨服務系統則需要相應的建置與整合測試。對重大權限、資料變更及公開 API,應再加上真正的契約與授權案例。這些檢查各自保護不同風險,不是靠增加一個綠勾就全部解決。

交給 reviewer 的最小紀錄

PR 說明應包含具體需求、影響邊界、已跑的測試,以及修正後如何驗收。對這個範例,簡單寫「確認 100,000 元不要求額外檢查、100,001 元要求;正常 5 個測試通過,錯誤運算子會被拒絕」就比「已完整測試」更有資訊。

再附實際提交 SHA、Actions run、測試結果及規則驗收狀態。CI 綠燈、reviewer 同意、主線合併、正式部署與使用者驗收,應各自有紀錄。這樣同一份工作流才能在功能增加後繼續提供可追溯的證據。

來源與實測範圍

官方依據包括 GitHub CI、Workflow syntax、Rulesets、setup-node、Node 測試執行器及npm ci。範例與金額測試為原創教學,無真實客戶資料。

本機命令、正常與故意失敗的測試已有紀錄;對外服務、讀者帳號權限、正式部署及商業成效不在驗證範圍。封面為使用者提供、由 AI 生成與編排的原創概念圖,並非 Actions 畫面截圖。本文由 AI 協助修訂與查核,未宣稱具名人工審核;Derek Chou 為 TARAISG AI 編輯計畫的專題角色。

內容提供:TARAISG。本文由 AI 協助整理與查核;專題編輯為天地人 AI 編輯計畫的策展角色,未宣稱經具名人工或專家審核。

AI 生成內容

本文由 TARAISG(TIANDIREN AI SOLUTION GROUP)使用 AI 模型產生正文、整理來源並設計實務工具。方法依據與限制列於文末;案例為明確標示的教學假設。未有具名紀錄時,不宣稱經人工或專家審核。

查看內容製作與更正說明

立即領!558元學習投資折抵金

能力投資季。立即領取 558 元學習金!全站線上課立即折抵。只需填寫 Email,即可輕鬆獲得,先領起來,不要錯過!

立即領!559元學習投資折抵金

能力投資季。立即領取 559 元學習金!全站線上課立即折抵。只需填寫 Email,即可輕鬆獲得,先領起來,不要錯過!

立即領!579 元學習金

學習,看見新可能。 10/14 前領取 579 元折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

立即領!599 元學習金

學習,帶來新可能。 09/09 前領取 558 元折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

立即領!558 元學習金

學習,發現新大陸。 8/29 前領取 558 元折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

立即領!559 元學習金

學習,連結新亮點。 8/14 前領取 559 元折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

立即領!555 元學習金

學習,發現更多視角。 6/14 前領取 555 元折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

立即領!556 元學習金

學習,累積無限可能。 5/29 前領取 556 元折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

立即領!557 元學習金

學習,讓我們發現未曾想像的可能!5/14 前領取 557 元折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

立即領!579 元折抵金

知識就是力量,專業成就未來!3/18 前領取 579 元課程折抵金,解鎖數百堂高品質線上課程,提升職場競爭力與專業技能。只需填寫Email,即可輕鬆獲得,投資自己從現在開始!

年終學習金

年終之餘用學習投資自己!填入 Email ,立即領取 588 元年終學習金!數百堂線上課程立即折抵,先領取收藏起來!