13 KiB
Gitea Node Action 範本
Node(JavaScript)action 讓你用 JavaScript 撰寫 action 邏輯,直接跑在 runner 內建的 Node runtime 上。相較於 composite(純 YAML 組合 step)與 Docker(包 image)action,node action 適合需要程式邏輯、呼叫 API、跨平台的情境,且啟動速度比 Docker action 快。
本文件整理 node action 的 action.yml 中所有可用參數、說明與限制,並特別標出 Gitea 與 GitHub Actions 的差異。範例皆對應本 repo 的 action.yml 與 src/index.js。
語法基準:Gitea Actions 以相容 GitHub Actions metadata 語法為目標,但兩者有明確差異(見「Gitea vs GitHub」章節)。Gitea 端的行為亦受底層
actrunner 版本影響——尤其支援的 Node 版本——實作前建議以測試機驗證。
目錄
- 完整結構總覽
- 頂層參數
inputs(輸入參數)outputs(輸出)runs(執行設定)- 在 JavaScript 內取值 / 設值
- 建置與打包(相依套件)
- Node action 的限制與注意事項
- Gitea vs GitHub Actions 差異
- 本 repo 範例對照
- 參考來源
完整結構總覽
name: 'Gitea Node Template' # 必填
description: 'Gitea Node 範本' # 必填
author: 'Jeffery' # 選填
inputs: # 選填,定義輸入參數
message:
description: '輸入訊息'
required: false
default: 'Hello, World!'
outputs: # 選填,定義輸出
message:
description: '輸出訊息' # node action 只需 description,不需 value
runs: # 必填
using: 'node24' # 必填,node runtime(最新版;見版本說明)
main: 'src/index.js' # 必填,進入點 JS 檔
pre: 'setup.js' # 選填,main 之前執行
pre-if: "always()" # 選填,pre 的條件,預設 always()
post: 'cleanup.js' # 選填,main 之後執行
post-if: "always()" # 選填,post 的條件,預設 always()
branding: # 選填(Marketplace 用,Gitea 內部可省略)
icon: 'activity'
color: 'blue'
📌 檔名只能是
action.yml或action.yaml,放在 action repo 根目錄。
頂層參數
| 參數 | 必填 | 說明 |
|---|---|---|
name |
✅ | Action 名稱。 |
description |
✅ | Action 簡短說明。 |
author |
❌ | 作者名稱。 |
inputs |
❌ | 輸入參數定義(見下)。 |
outputs |
❌ | 輸出定義(見下)。 |
runs |
✅ | 執行設定;node action 用 using: 'node24' + main。 |
branding |
❌ | Marketplace 顯示用的 icon 與 color。 |
inputs(輸入參數)
每個 input 是 inputs.<input_id> 底下的一組設定。<input_id> 必須以字母或底線開頭,只能含英數、-、_:
| 欄位 | 必填 | 說明 |
|---|---|---|
description |
✅ | 參數說明。 |
required |
❌ | 是否必填,布林值,預設 false。 |
default |
❌ | 預設值;呼叫端沒傳時採用。只能是字串。 |
deprecationMessage |
❌ | 標記此 input 已棄用,使用時記錄警告訊息。 |
呼叫端傳值(用 with):
- uses: ./
with:
message: 'Hi there'
✅ 與 composite 的關鍵差異:node action 會自動把每個 input 轉成
INPUT_<NAME>環境變數——名稱轉大寫、空白換成底線(例:inputmy message→INPUT_MY_MESSAGE)。在 JS 內即可用process.env.INPUT_MESSAGE或core.getInput('message')取值。⚠️
required: true不會在缺值時自動報錯——runner 只是標記語意,實際檢查要自己在程式裡做(或用core.getInput('x', { required: true }))。input 值一律是字串;數字、布林傳進來也會變字串(例如
"true"),比較時要留意。
outputs(輸出)
node action 的 output 只需要 description,不需要(也不該有)composite 那種 value 欄位——實際的值是在執行時由程式寫入:
| 欄位 | 必填 | 說明 |
|---|---|---|
description |
✅ | 輸出說明。 |
在 JS 內設定 output → 寫入 $GITHUB_OUTPUT 檔案(或用 core.setOutput):
const fs = require('fs');
const os = require('os');
fs.appendFileSync(process.env.GITHUB_OUTPUT, `message=Hello${os.EOL}`);
// 或(需要 @actions/core): core.setOutput('message', 'Hello');
呼叫端取用 output:
- id: node-template
uses: ./
- run: echo "${{ steps.node-template.outputs.message }}"
📏 大小限制:單一 job 的 outputs 上限 1 MB;一次 workflow run 全部 outputs 合計上限 50 MB。大量資料請改用 artifact。
runs(執行設定)
node action 的 runs 欄位:
| 欄位 | 必填 | 說明 |
|---|---|---|
using |
✅ | Node runtime。最新為 node24(本 repo 採用);亦可用 node20 / node16。實際可用版本取決於 runner(見下方 Gitea 差異)。 |
main |
✅ | 進入點 JS 檔(例:src/index.js 或打包後的 dist/index.js)。 |
pre |
❌ | 在 main 之前、job 開始時執行的 JS 檔(可做前置設定)。 |
pre-if |
❌ | 決定 pre 是否執行的條件,預設 always()。 |
post |
❌ | 在 main 之後執行的 JS 檔(可做清理、即使 main 失敗仍會跑)。 |
post-if |
❌ | 決定 post 是否執行的條件,預設 always()。 |
⚠️
pre不支援 local action:直接放在同一 repo、用uses: ./呼叫的 local action 無法使用runs.pre。pre/post也是 node action 專屬(composite / Docker 沒有)。
在 JavaScript 內取值 / 設值
node action 進入點是一支普通的 Node 程式。兩種常見寫法:
A) 零相依(本 repo 採用)——直接讀環境變數、寫檔案,無需 npm install:
const message = process.env.INPUT_MESSAGE ?? 'Hello, World!'; // 讀 input
fs.appendFileSync(process.env.GITHUB_OUTPUT, `message=${message}\n`); // 寫 output
console.log(`message=${message}`); // 日誌
process.exit(1); // 讓 step 失敗
B) 使用官方 toolkit @actions/core——語意更清楚,處理跳脫與多行值較穩:
const core = require('@actions/core');
const message = core.getInput('message'); // 讀 input(等同 INPUT_MESSAGE)
core.setOutput('message', message); // 設 output
core.info('...'); // 日誌
core.setFailed('錯誤訊息'); // 記錄失敗並以非零碼結束
需要呼叫 Gitea / GitHub API 時再加 @actions/github(提供已驗證的 REST client 與 github.context)。
建置與打包(相依套件)
- 沒有相依套件(如本 repo):
main直接指向原始src/index.js即可,Gitea 不需要 build 步驟。 - 有相依套件(用了
@actions/core等):runner 不會幫你npm install,你必須把相依一起帶進 repo。二選一:- 打包(建議):用
@vercel/ncc把原始碼與相依編成單一檔,再把main指到它:並改npm i -D @vercel/ncc npx ncc build src/index.js -o dist # 產生 dist/index.jsaction.yml:main: 'dist/index.js'。打包後的dist/要 commit 進 repo。 - 直接 commit
node_modules:可行但體積大、易出問題,一般不建議。
- 打包(建議):用
用打包方式時,記得每次改 code 都重新
ncc build並把dist/一起提交,否則 action 跑的是舊版。
Node action 的限制與注意事項
-
相依不會自動安裝 runner 不會在 action repo 內跑
npm install。要嘛零相依,要嘛把相依打包 / commit 進 repo(見上一節)。 -
required: true不會自動擋 缺少必填 input 時 runner 不會報錯,要自己在程式裡驗證。 -
input 一律是字串
INPUT_*/core.getInput拿到的都是字串,數字與布林需自行轉型。 -
output 有大小上限 單 job 1 MB、單次 run 合計 50 MB;超量請用 artifact。
-
main路徑相對於 action 根目錄main: src/index.js指的是相對於 action repo 根目錄的路徑,不受呼叫端工作目錄影響。要讀 action 自帶的其他檔案時,用__dirname或process.env.GITHUB_ACTION_PATH定位,不要用相對於呼叫端的路徑。 -
pre不支援 local action、且pre/post為 node 專屬 見runs章節。 -
Node 版本要對得上 runner
using指定的版本必須是該 runner 支援的版本,否則 action 直接被拒(見下方 Gitea 差異)。 -
跨 step 共享環境變數 / PATH 在程式內寫入
$GITHUB_ENV、$GITHUB_PATH指向的檔案,可讓後續 step取得對應的環境變數 / PATH。
Gitea vs GitHub Actions 差異
Gitea Actions 不是 GitHub Actions 的 100% 複製品。撰寫 node action 時特別注意:
| 項目 | Gitea 行為 |
|---|---|
| 支援的 Node 版本 | runs.using 可用的 node 版本取決於 act runner 版本:node20 需 runner ≥ v0.2.6;node24(最新,本 repo 採用)需較新的 runner。若 runner 太舊,會報錯 The runs.using key in action.yml must be one of: [composite docker node12 node16 node20 go], got node24——此時請升級 act runner,或暫時退回 node20。GitHub 端自 2026/03 起 node24 已為 JS action 預設。 |
using: 'go' |
Gitea 額外支援 using: 'go' 寫 Go action(GitHub 沒有)。 |
| 表達式函式 | 依官方比較文件,僅保證支援 always();success() / failure() / cancelled() / hashFiles() 等其他函式視 act runner 版本而定,不保證可用——寫 if:(含 pre-if / post-if)前先在測試機驗證。 |
uses 支援絕對 URL |
可寫 uses: https://github.com/actions/checkout@v4 或 uses: http://your_gitea/owner/repo@branch,不限同站 action。 |
| context 檢查較寬鬆 | Gitea 不檢查 context 可用性,env context 可用在比 GitHub 更多的位置(但不代表可攜,跨到 GitHub 會失敗)。 |
| 被忽略的 job 欄位 | jobs.<job_id>.timeout-minutes、jobs.<job_id>.continue-on-error、jobs.<job_id>.environment 會被忽略。 |
runs-on |
只接受簡單格式 runs-on: xyz 或 runs-on: [xyz],不支援複雜表達式。 |
| annotations / problem matchers | 不支援,會被忽略。 |
permissions scope |
支援 permissions,但沒有 GitHub 專屬的 statuses / checks / deployments / id-token / security-events / pages;Gitea 有自己的 code / releases / wiki / projects。 |
上表以 Gitea 官方文件為準;
actrunner 持續更新,部分限制(尤其表達式函式與 Node 版本)可能隨版本放寬,仍以你環境的實測為準。
本 repo 範例對照
- Action 定義:
action.yml(using: node24+main: src/index.js) - 進入點程式:
src/index.js(零相依:讀INPUT_MESSAGE、寫$GITHUB_OUTPUT) - 專案設定:
package.json - CI 呼叫範例:
.gitea/workflows/ci.yaml
CI 的 BUILD job 呼叫本 action、後續 job 取用其 output:
build:
outputs:
message: ${{ steps.build.outputs.message }}
steps:
- uses: actions/checkout@${{ vars.ACTION_CHECKOUT_VERSION }}
- id: build
uses: ./
result:
needs: [build, test]
steps:
- run: echo "${{ needs.build.outputs.message }}"