Files
setup-claude/readme.md
T
2026-07-17 01:55:20 +00:00

272 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Gitea Composite Action 範本
Composite(複合)action 讓你把多個 step 打包成一個可重用的 action,用 YAML 直接組合 shell 指令或呼叫其他 action,不需要寫 JavaScript 或包 Docker image。
本文件整理 `action.yml` 中**所有可用參數、說明與限制**,並特別標出 **Gitea 與 GitHub Actions 的差異**。範例皆對應本 repo 的 [`action.yml`](./action.yml)。
> 語法基準:Gitea Actions 以相容 GitHub Actions metadata 語法為目標,但兩者有明確差異(見「Gitea vs GitHub」章節)。Gitea 端的行為亦受底層 [`act`](https://gitea.com/gitea/act) runner 版本影響,實作前建議以測試機驗證。
---
## 目錄
- [完整結構總覽](#完整結構總覽)
- [頂層參數](#頂層參數)
- [`inputs`(輸入參數)](#inputs輸入參數)
- [`outputs`(輸出)](#outputs輸出)
- [`runs.steps`(步驟)](#runssteps步驟)
- [Composite action 的限制與注意事項](#composite-action-的限制與注意事項)
- [Gitea vs GitHub Actions 差異](#gitea-vs-github-actions-差異)
- [本 repo 範例對照](#本-repo-範例對照)
- [參考來源](#參考來源)
---
## 完整結構總覽
```yaml
name: 'Gitea Composite Template' # 必填
description: 'Gitea Composite 範本' # 必填
author: 'Jeffery' # 選填
inputs: # 選填,定義輸入參數
message:
description: '輸入訊息'
required: false
default: 'Hello, World!'
outputs: # 選填,定義輸出
message:
description: '輸出訊息'
value: ${{ steps.exchange.outputs.message }} # composite 必填 value
runs: # 必填
using: 'composite' # 必填,固定為 composite
steps: # 必填,至少一個 step
- name: Exchange
id: exchange
env: # env 只能設在 step 層
MESSAGE: ${{ inputs.message }}
run: echo "message=$MESSAGE" >> "$GITHUB_OUTPUT"
shell: bash # 用 run 時強制必填
branding: # 選填(Marketplace 用,Gitea 內部可省略)
icon: 'activity'
color: 'blue'
```
> 📌 檔名**只能**是 `action.yml` 或 `action.yaml`,放在 action repo 根目錄。
---
## 頂層參數
| 參數 | 必填 | 說明 |
|------|------|------|
| `name` | ✅ | Action 名稱。 |
| `description` | ✅ | Action 簡短說明。 |
| `author` | ❌ | 作者名稱。 |
| `inputs` | ❌ | 輸入參數定義(見下)。 |
| `outputs` | ❌ | 輸出定義(見下)。 |
| `runs` | ✅ | 執行設定;composite 固定用 `using: 'composite'` + `steps`。 |
| `branding` | ❌ | Marketplace 顯示用的 `icon``color`。 |
---
## `inputs`(輸入參數)
每個 input 是 `inputs.<input_id>` 底下的一組設定:
| 欄位 | 必填 | 說明 |
|------|------|------|
| `description` | ✅ | 參數說明。 |
| `required` | ❌ | 是否必填,布林值,預設 `false`。 |
| `default` | ❌ | 預設值;呼叫端沒傳時採用。**只能是字串**。 |
| `deprecationMessage` | ❌ | 標記此 input 已棄用,使用時發出警告訊息。 |
**在 composite 內取用 input** → 用 `${{ inputs.<input_id> }}`
```yaml
inputs:
message:
description: '輸入訊息'
required: false
default: 'Hello, World!'
```
**呼叫端傳值**(用 `with`):
```yaml
- uses: ./
with:
message: 'Hi there'
```
> ⚠️ **重要差異**composite action **不會**自動產生 `INPUT_<NAME>` 環境變數(Docker / JS action 才有)。在 composite 內**只能**用 `${{ inputs.<id> }}` context 取值;若要當環境變數用,需自己在 step 的 `env:` 對應一次(如範例的 `MESSAGE`)。
>
> input 值一律是**字串**;數字、布林傳進來也會變字串(例如 `"true"`),比較時要留意。
---
## `outputs`(輸出)
composite action 的 output **與 JavaScript / Docker action 不同****必須**額外提供 `value`,明確指定值從哪個 step 來。
| 欄位 | 必填 | 說明 |
|------|------|------|
| `description` | ✅ | 輸出說明。 |
| `value` | ✅(composite | 輸出值,通常對應某個 step 的 output`${{ steps.<id>.outputs.<name> }}`。 |
**step 內設定 output** → 寫入 `$GITHUB_OUTPUT` 檔案:
```yaml
outputs:
message:
description: '輸出訊息'
value: ${{ steps.exchange.outputs.message }}
runs:
using: 'composite'
steps:
- id: exchange # 一定要有 id 才能被 value 引用
run: echo "message=Hello" >> "$GITHUB_OUTPUT"
shell: bash
```
**呼叫端取用 output**
```yaml
- id: composite-template
uses: ./
- run: echo "${{ steps.composite-template.outputs.message }}"
```
---
## `runs.steps`(步驟)
composite 的核心。`steps` 是陣列,每個 step 支援下列欄位:
| 欄位 | 必填 | 說明 |
|------|------|------|
| `run` | 二選一 | 要執行的 shell 指令;與 `uses` 二擇一。 |
| `shell` | ✅(用 `run` 時) | **用 `run` 時強制必填**(見下方限制)。例:`bash``pwsh``sh``python`。 |
| `uses` | 二選一 | 呼叫另一個 action;與 `run` 二擇一。 |
| `with` | ❌ | 搭配 `uses`,傳入該 action 的 inputs。 |
| `name` | ❌ | step 顯示名稱。 |
| `id` | ❌ | step 識別碼;要引用該 step 的 outputs 時必填。 |
| `env` | ❌ | 此 step 的環境變數(**只能設在 step 層,不能設在 `runs` 層**)。 |
| `working-directory` | ❌ | 此 step 的工作目錄。 |
| `if` | ❌ | 條件式,決定是否執行此 step。 |
| `continue-on-error` | ❌ | 失敗時是否繼續,布林值。 |
---
## Composite action 的限制與注意事項
以下是實務上最容易踩雷的地方:
1. **`runs.env` 不支援**
環境變數**不能**設在 `runs:` 層,只能設在個別 step 的 `env:`(或呼叫端的 job / workflow 層)。設在 `runs.env` 會被直接忽略,變數會是空的。
```yaml
# ❌ 錯誤:runs 層 env 會被忽略
runs:
using: 'composite'
env:
MESSAGE: ${{ inputs.message }}
# ✅ 正確:設在 step 上
runs:
using: 'composite'
steps:
- env:
MESSAGE: ${{ inputs.message }}
run: echo "$MESSAGE"
shell: bash
```
2. **每個 `run` step 都必須指定 `shell`**
在一般 workflow 裡 `shell` 可省略,但 composite action 內**強制必填**,否則會報錯。
3. **outputs 必須明確給 `value`**
不像 JS/Docker actioncomposite 的 output 一定要用 `value: ${{ steps.<id>.outputs.<name> }}` 指定來源。
4. **input 用 `inputs` context,沒有 `INPUT_` 環境變數**
如前述,composite 內取 input 只能 `${{ inputs.<id> }}`,不會有 `INPUT_MESSAGE` 這種環境變數。
5. **不能直接使用 `secrets`**
composite action 內**無法**直接讀 `${{ secrets.* }}`,需要由呼叫端透過 `inputs` 傳進來。
6. **不支援 `pre` / `post`**
composite / 本機(localaction **不支援** `runs.pre`、`runs.post`(那是 JS action 專屬)。需要前置/後置動作就用一般的 step 排序。
7. **父層的 `if` 不會傳遞進來**
呼叫端 step 上的 `if` 只決定「要不要跑這個 composite」;一旦進入 composite,內部 step 是**乾淨狀態**,父層條件不會自動套用到每個子 step。子 step 要條件判斷需各自寫 `if`。
8. **step 之間共享環境變數 / PATH**
在某個 step 寫入 `$GITHUB_ENV`、`$GITHUB_PATH` 的值,可被**同一個 composite 內後續 step**使用。
9. **引用 action 內附檔案用 `${{ github.action_path }}`**
要跑 action 目錄裡自帶的腳本時,用 `$GITHUB_ACTION_PATH` / `${{ github.action_path }}` 定位,不要用相對路徑(執行時工作目錄是呼叫端的 repo,不是 action 目錄)。
```yaml
- run: "$GITHUB_ACTION_PATH/scripts/run.sh"
shell: bash
```
10. **`shell: bash` 的預設旗標**
`shell: bash` 實際會展開成 `bash --noprofile --norc -e -o pipefail {0}`
- `-e`:任一指令失敗立即中止 step。
- `-o pipefail`:pipe 中任一段失敗即視為失敗。
- 若某行預期可能失敗又不想讓 step 掛掉,加上 `|| true`。
11. **可巢狀,但子 action 繼承有規則**
composite 內可用 `uses` 再呼叫其他 action;巢狀 step 可存取上層的 input,也可覆寫。避免無限遞迴。
---
## Gitea vs GitHub Actions 差異
Gitea Actions **不是** GitHub Actions 的 100% 複製品。撰寫 action 時特別注意:
| 項目 | Gitea 行為 |
|------|-----------|
| **表達式函式** | 依官方比較文件,**僅保證支援 `always()`**`success()` / `failure()` / `cancelled()` / `hashFiles()` 等其他函式視 `act` runner 版本而定,不保證可用——寫 `if:` 前先在測試機驗證。 |
| **`uses` 支援絕對 URL** | 可寫 `uses: https://github.com/actions/checkout@v4` 或 `uses: http://your_gitea/owner/repo@branch`,不限同站 action。 |
| **composite 內用絕對 URL** | ⚠️ 部分 runner **不支援**在 composite action 裡用絕對 URL 的 `uses`;絕對 URL 建議只用在 workflow step。 |
| **Go actions** | Gitea 額外支援 `using: 'go'` 寫 Go actionGitHub 沒有)。 |
| **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 官方文件為準;`act` runner 持續更新,部分限制(尤其表達式函式)可能隨版本放寬,仍以你環境的實測為準。
---
## 本 repo 範例對照
- Action 定義:[`action.yml`](./action.yml)
- CI 呼叫範例:[`.gitea/workflows/ci.yaml`](./.gitea/workflows/ci.yaml)
CI 中先呼叫本 action、再取用其 output
```yaml
- name: Testing
id: composite-template
uses: ./
- name: Feedback
run: echo "${{ steps.composite-template.outputs.message }}"
```
---
## 參考來源
- [GitHub Actions — Metadata syntax for actions](https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax)
- [Gitea — Compared to GitHub Actions](https://docs.gitea.com/usage/actions/comparison)
- [Gitea — Actions FAQ](https://docs.gitea.com/usage/actions/faq)
- [actions/runner — Composite run steps ADR](https://github.com/actions/runner/blob/main/docs/adrs/0549-composite-run-steps.md)
- [actions/runner#665 — INPUT_* env vars missing in composite actions](https://github.com/actions/runner/issues/665)