![]()
你的團隊有47個倉庫共用同一套構建腳本嗎?GitHub Actions用戶平均每個組織維護23份重復的YAML配置,而官方4年前就埋了解法。
這套解法叫Custom Actions(自定義動作)。不是新功能,是大多數團隊直到CI/CD復雜度爆炸才想起來的基礎設施。今天把三種技術路線、選型陷阱和發(fā)布流程一次說清。
Composite:不會JS也能造輪子
最被低估的類型。Composite Action(組合動作)允許你把多個workflow步驟打包成一個可復用單元,零JavaScript代碼。
典型場景:每個Node項目都要重復「裝Node→選包管理器→配緩存→裝依賴→構建」這五步。復制粘貼23次后,任何緩存策略調整都是災難。
Composite的解法是把這五步變成一行調用:
```yaml name: 'Setup Node Project' inputs: node-version: default: '20' package-manager: default: 'npm' outputs: cache-hit: value: ${{ steps.cache.outputs.cache-hit }} runs: using: composite steps: - uses: actions/setup-node@v4 with: node-version: ${{ inputs.node-version }} # 條件分支處理pnpm/yarn/npm三種包管理器 # 動態(tài)計算緩存目錄路徑 - uses: actions/cache@v4 with: path: ${{ steps.cache-dir.outputs.dir }} key: ${{ runner.os }}-${{ inputs.package-manager }}-${{ hashFiles('**/lockfile') }} ```
關鍵設計:inputs(輸入參數)和outputs(輸出值)讓這個動作像函數一樣被調用。調用方只關心「給我Node環(huán)境」,不關心內部是pnpm還是yarn。
限制也很明確:Composite不能跑后臺服務,不能跨runner執(zhí)行,復雜邏輯需要借助shell腳本。但對于「步驟復用」這個單一問題,它是維護成本最低的選擇。
JavaScript Action:需要跑在GitHub托管機上的邏輯
當Composite的shell腳本變得難以維護,或者需要調用GitHub API、處理異步操作時,切到JavaScript Action(JavaScript動作)。
技術棧固定:Node.js 20,@actions/core工具包,@actions/github獲取上下文。打包方式有兩種——
方案A:把node_modules全提交進倉庫。簡單,但倉庫體積膨脹。
方案B:用@vercel/ncc把依賴打包成單文件。推薦,但要多一步構建流程。
一個常被忽略的細節(jié):JavaScript Action在GitHub托管的runner(運行器)上執(zhí)行,能直接操作runner的文件系統(tǒng)、環(huán)境變量和網絡。這是它和Docker Action的核心差異。
選型信號:如果你的邏輯需要「在runner環(huán)境里做點什么」,選JS;如果需要「帶一個完整環(huán)境去做點什么」,看下面。
Docker Action:環(huán)境隔離的終極手段
Docker Action(Docker動作)把整個運行時打包進鏡像。適合兩種極端場景:依賴特定操作系統(tǒng)工具鏈(比如某個Linux發(fā)行版的原生庫),或者對環(huán)境隔離有強需求(比如跑不可信代碼)。
代價明顯:每次調用都要拉鏡像,冷啟動慢。GitHub建議用預構建鏡像而非Dockerfile現(xiàn)場構建,能把啟動時間從分鐘級壓到秒級。
三種類型對比表(決策用):
| 維度 | Composite | JavaScript | Docker | |:---|:---|:---|:---| | 啟動速度 | 即時 | 秒級 | 分鐘級(無緩存)| | 環(huán)境依賴 | 繼承runner | Node.js 20 | 任意 | | 適用場景 | 步驟復用 | 復雜邏輯+API調用 | 環(huán)境隔離+特殊工具鏈 | | 維護成本 | 最低 | 中等 | 最高 |
版本策略:v1標簽背后的陷阱
發(fā)布到GitHub Marketplace(應用市場)只是第一步。真正的坑在版本管理。
GitHub官方推薦「浮動標簽+固定提交」雙軌制:
? 用戶側寫`uses: your-action@v1`,享受自動更新
? 維護側同時打`v1`標簽和`v1.2.3`語義化標簽,重大變更時把`v1`指向新版本
但這套機制有個反直覺的漏洞:標簽是可變的。如果攻擊者劫持了你的倉庫,能把`v1`指向惡意提交。供應鏈安全團隊更推薦讓用戶鎖死SHA(提交哈希),代價是失去自動更新。
折中方案:提供`v1`便利標簽,同時在README用大號字體標注「生產環(huán)境建議鎖定SHA」。
測試:本地能跑通才算完成
Actions的測試一直是痛點。官方沒給本地模擬器,社區(qū)方案有三類——
nektos/act:用Docker在本地跑GitHub Actions,最接近真實環(huán)境,但鏡像體積大、部分功能缺失。
@github/local-action:官方實驗性工具,只支持JavaScript Action,調試體驗尚可。
最務實的路線:把核心邏輯抽成純函數,用Jest/Vitest單元測試覆蓋;Action本體只做「參數解析+函數調用」的薄封裝。這樣即使沒法本地跑完整workflow,邏輯正確性也有保障。
一個來自GitHub工程師的實操建議:在Action倉庫里建`.github/workflows/test.yml`,用矩陣策略(matrix strategy)測試多平臺(ubuntu/windows/macos)和多版本組合。這比本地模擬更可靠,缺點是推送才能觸發(fā)。
發(fā)布前的檢查清單:action.yml元數據完整(name/description/inputs/outputs/runs)、README含完整調用示例、LICENSE文件存在(MIT最通用)、版本標簽已打。Marketplace的審核是自動的,但缺失任一項都會導致搜索排名靠后。
最后問一句:你們團隊的CI/CD配置現(xiàn)在有多少份重復代碼?如果超過10份,Composite Action可能是最快見效的還債方案。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.