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 }}"