Gitea Actions 的設計
Gitea Actions 有多個組件。本文件將分別描述它們。
Act
nektos/act 項目是一個出色的工具,允許您在本地運行 GitHub Actions。 我們受此啟發,想知道是否可以為 Gitea 運行操作。
然而,雖然 nektos/act 被設計為命令行工具,但我們實際上需要的是一個專門為 Gitea 進行修改的 Go 庫。 所以我們將其分叉為 gitea/act。
這是一個軟分叉,將定期跟隨上游。 儘管添加了一些自定義提交,但我們將盡量避免更改太多原始代碼。
分叉的 act 只是 Gitea 特定用法的 shim 或適配器。 已經進行了一些額外的提交,例如:
- 將執行日誌輸出到 logger 鉤子,以便可以報告給 Gitea
- 禁用 GraphQL URL,因為 Gitea 不支持它
- 為每個作業啟動一個新容器,而不是重用,以確保隔離。
這些修改沒有理由合併到上游。 如果用戶只想在本地運行受信任的操作,這些修改沒有意義。
然而,未來可能會有重疊,例如兩個項目都需要的錯誤修復或新功能。 在這些情況下,我們將把更改貢獻回上游倉庫。
Act runner
Gitea 的 runner 被稱為 act runner,因為它基於 act。
像其他 CI runner 一樣,我們將其設計為 Gitea 的外部部分,這意味著它應該在與 Gitea 不同的服務器上運行。
為了確保 runner 連接到正確的 Gitea 實例,我們需要使用令牌註冊它。 此外,runner 將向 Gitea 介紹自己並通過報告其標籤來聲明它可以運行的作業類型。
前面提到過,工作流程文件中的 runs-on: ubuntu-latest
意味著作業將在具有 ubuntu-latest
標籤的 runner 上運行。
但是 runner 如何知道運行 ubuntu-latest
?答案在於將標籤映射到環境。
這就是為什麼在註冊期間添加自定義標籤時,您需要輸入一些複雜的內容,如 my_custom_label:docker://centos:7
。
這意味著 runner 可以接受需要在 my_custom_label
上運行的作業,並將其通過 docker 容器運行,映像為 centos:7
。
然而,docker 並不是唯一的選擇。
act 還支持直接在主機上運行作業。
這是通過標籤如 linux_arm:host
實現的。
這個標籤表示 runner 可以接受需要在 linux_arm
上運行的作業,並直接在主機上運行它。
標籤的設計遵循格式 label[:schema[:args]]
。
如果省略 schema,則默認為 host
。
所以,
my_custom_label:docker://node:18
: 使用node:18
Docker 映像運行標籤為my_custom_label
的作業。my_custom_label:host
: 直接在主機上運行標籤為my_custom_label
的作業。my_custom_label
: 與my_custom_label:host
相同。my_custom_label:vm:ubuntu-latest
: (僅示例,未實現)使用ubuntu-latest
ISO 的虛擬機運行標籤為my_custom_label
的作業。
通信協議
由於 act runner 是 Gitea 的獨立部分,我們需要一個協議來讓 runner 與 Gitea 實例通信。 然而,我們認為讓 Gitea 監聽一個新端口不是一個好主意。 相反,我們希望重用 HTTP 端口,這意味著我們需要一個與 HTTP 兼容的協議。 我們選擇使用 gRPC over HTTP。
我們使用 actions-proto-def 和 actions-proto-go 來將它們連接起來。 有關 gRPC 的更多信息可以在 其網站 上找到。
網絡架構
讓我們來看看整體網絡架構。 這將幫助您排除一些問題,並解釋為什麼用 Gitea 實例的回環地址註冊 runner 是個壞主意。
圖片中標記了四個網絡連接,箭頭的方向表示建立連接的方向。
連接 1,act runner 到 Gitea 實例
act runner 必須能夠連接到 Gitea 以接收任務並發送回執行結果。
連接 2,作業容器到 Gitea 實例
作業容器與 runner 有不同的網絡命名空間,即使它們在同一台機器上。
如果工作流程中有 actions/checkout@v4
,它們需要連接到 Gitea 以獲取代碼。
運行某些作業並不總是需要獲取代碼,但在大多數情況下是必需的。
如果您使用回環地址註冊 runner,當它在同一台機器上時,runner 可以連接到 Gitea。 但是,如果作業容器嘗試從 localhost 獲取代碼,則會失敗,因為 Gitea 不在同一容器中。
連接 3,act runner 到互聯網
當您使用一些操作如 actions/checkout@v4
時,act runner 會下載腳本,而不是作業容器。
默認情況下,它從 github.com 下載,因此需要訪問互聯網。如果您將 DEFAULT_ACTIONS_URL
配置為 self
,則它將默認從您的 Gitea 實例下載。然後在下載操作本身時不會連接到互聯網。
它還默認從 Docker Hub 下載一些 docker 映像,這也需要訪問互聯網。
然而,訪問互聯網並不是絕對必要的。 您可以配置您的 Gitea 實例從您的內聯設施中獲取操作或映像。
事實上,您的 Gitea 實例可以同時作為操作市場和映像註冊表。 您可以將操作倉庫從 GitHub 鏡像到您的 Gitea 實例,並正常使用它們。 而 Gitea 容器註冊表 可以用作 Docker 映像註冊表。
連接 4,作業容器到互聯網
當使用如 actions/setup-go@v5
的操作時,可能需要從互聯網下載資源以在作業容器中設置 Go 語言環境。
因此,訪問互聯網是這些操作成功完成所必需的。
然而,這也是可選的。 您可以使用自己的自定義操作來避免依賴互聯網訪問,或者您可以使用打包的 Docker 映像來運行已安裝所有依賴項的作業。
總結
使用 Gitea Actions 只需要確保 runner 可以連接到 Gitea 實例。 訪問互聯網是可選的,但沒有它將需要一些額外的工作。 換句話說:runner 最好能夠自己查詢互聯網,但您不需要將其暴露在互聯網上(無論是入站還是出站)。
如果您在使用 Gitea Actions 時遇到任何網絡問題,希望上圖可以幫助您排除它們。