稍候片刻,月出文自明。
- name: Checkout repository
uses: https://data.forgejo.org/actions/checkout@v6
- name: Set up pnpm
uses: https://github.com/pnpm/action-setup@v4
- name: Set up Docker Buildx
uses: https://github.com/docker/setup-buildx-action@v4- name: Set up Docker Buildx
uses: https://github.com/docker/setup-buildx-action@v4
- name: Log in to CodeFloe Container Registry
uses: https://github.com/docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.CODEFLOE_REGISTRY_USERNAME }}
password: ${{ secrets.CODEFLOE_REGISTRY_TOKEN }}
- name: Extract Docker metadata
id: meta
uses: https://github.com/docker/metadata-action@v6
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest
type=sha
- name: Build and push Docker image
uses: https://github.com/docker/build-push-action@v7
with:
context: .
push: true
platforms: linux/amd64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}docker login codefloe.com -u <组织成员用户名>
# 在密码提示中输入具有 read:package 权限的 PAT。
docker pull codefloe.com/your-private-org/yohaku:latestgit push --atomic \
--force-with-lease="refs/heads/sync:$old_sync" \
--force-with-lease="refs/heads/main:$old_main" \
origin sync:sync main:main
前言
這篇文章的誕生純屬偶然。我的 GitHub 因為帳單強制送中,導致 Free 方案無法續用,私有儲存庫的 Workflow(沒錯,就是我在前幾篇文章裡寫的同步 Yohaku 上游和建置 Docker 映像檔那幾個)完全不能用。偏偏我需要在私有儲存庫跑 Workflow,只好遺憾地搬離 GitHub,另找能執行私有專案 CI 的 Git 服務。(So, GitHub, fxxk you.avif)
巧的是,最近找到一個伺服器位於歐洲的 Forgejo 服務——CodeFloe,相較於 Codeberg,它對 AI 的態度比較寬鬆,而且他們最近在新加坡架設了中繼伺服器,讓存取體驗改善不少。CI/CD(Actions + CrowCI)、Weblate、Renovate、Pages、MCP 等配套服務也一應俱全,因此不意外地成了遷移目的地。
把儲存庫從 GitHub 搬到 Forgejo 後,原本的 GitHub Actions 工作流程也得調整一番,才能在 Forgejo Actions 上執行。於是我抓來 AI(6.1 Sol)替我完成遷移,接下來就是它完成的內容。
這次遷移的目標是 CodeFloe 託管的 Forgejo Actions,涉及三個工作流程:同步 GitHub 上游程式碼、建置並發布 Docker 映像檔,以及部署到 EdgeOne Makers。遷移後已完成本機語法檢查和關鍵腳本驗證;本文不把這些結果視為已在 CodeFloe runner 上完整執行成功的證明。
以下設定方式可供遷移其他專案參考。其中 runner 標籤和基礎映像檔是針對 CodeFloe 環境設定的,遷移到自行架設的 Forgejo 時,須依實際設定調整。本文依據遷移時的工作流程,以及截至 2026 年 11 月 8 日查閱的官方文件整理。
先確認工作流程從哪裡讀取
Forgejo 預設讀取儲存庫中的 .forgejo/workflows/。只有該目錄不存在時,才會改讀 .github/workflows/。
因此,可以把需要遷移的檔案移到:
這裡有個容易忽略的影響:建立 .forgejo/workflows/ 後,Forgejo 不會繼續讀取 .github/workflows/ 中剩下的工作流程。
假設原本有十個 GitHub 工作流程,只遷移了三個,其餘七個仍可留給 GitHub 使用,但不會自動在 Forgejo 上執行。遷移前應先確認哪些工作流程需要在新平台上執行。
此外,還要在目標儲存庫設定中啟用 Actions,並確認服務中有可用的 runner。排程任務的工作流程應放在預設分支;手動執行前也應確認目標服務的工作流程偵測規則。
明確指定 Action 的來源
GitHub Actions 常見的寫法是:
這種寫法依賴平台設定的預設 Action 來源。Forgejo 服務的預設來源可能與 GitHub 不同,也不應直接假設 CodeFloe 的預設 Action 來源是 GitHub。
遷移時可以使用完整 URL,避免產生歧義:
但完整 URL 只解決「從哪裡下載」的問題。Action 能夠下載,不代表它能在 Forgejo 上正常運作。
還需要檢查它是否呼叫 GitHub API、是否寫死 github.com、是否依賴 GitHub 的快取或建置成品服務,以及需要什麼樣的 Node.js 和系統環境。
重新檢查 runner,而不是只保留 ubuntu-latest
GitHub 託管的 runner 通常預裝了許多工具。Forgejo 的 runner 環境則由服務管理員決定,即使都叫 ubuntu-latest,實際執行環境也可能不同。
對於同步程式碼、執行 Node.js CLI 這類任務,本次遷移透過容器固定基礎環境:
這個映像檔提供了專案需要的 Node.js、git 和 bash。其他專案若需要 Python、編譯工具或額外的系統函式庫,仍須自行準備。
Docker 建置則需要另外處理。容器裡有 Docker CLI,不代表能連接 Docker daemon。CodeFloe 為此提供了 docker runner 標籤:
這裡明確指定 amd64,是因為專案現有的 Dockerfile 中,部分相依套件固定安裝 x64 版本。如果只使用通用標籤,可能會被分配到不同架構的 runner。
這次針對 CodeFloe 的 Alpine Docker 環境,在執行 JavaScript Action 前安裝相依套件:
這段指令適用於 Alpine。自行架設的 runner 若使用 Debian,應改用對應的映像檔或套件管理方式。CodeFloe 的 arm64 Docker runner 還有其他限制,例如覆寫 container: 映像檔可能導致 Docker daemon 無法使用,應依照平台文件設定。
區分儲存庫權杖、上游權杖和映像檔儲存庫權杖
驗證是這次遷移中最需要重新釐清的部分。原本在 GitHub 上可用的 GITHUB_TOKEN,無法直接承擔新平台上的所有職責。
Forgejo 會為工作流程建立暫時權杖,提供 forgejo.token、FORGEJO_TOKEN 等存取方式,也保留了 github.token、GITHUB_TOKEN 等相容名稱。
這個自動權杖可以用來操作目前的儲存庫,但有一項重要的行為:
因此,不同任務應選用不同的憑證:
操作
本次使用的憑證
拉取目前的 Forgejo 儲存庫
自動任務權杖
推送部署用調整分支,後續步驟繼續部署
自動任務權杖
同步後推送 `main`,需要觸發建置和部署
具有儲存庫寫入權限的 CodeFloe PAT
拉取私有 GitHub 上游
具有上游讀取權限的 GitHub PAT
發布 CodeFloe 容器套件
具有套件寫入權限的 CodeFloe PAT
例如,同步工作流程需要以 PAT 作為憑證執行 checkout,讓後續推送能夠觸發下游工作流程:
GitHub 上設定的 Secrets 不會隨 Git 儲存庫自動遷移,必須在 CodeFloe 中重新設定。
另外,GitHub 的:
不能作為 Forgejo 中授權成功的依據。Forgejo 對部分權限欄位的處理與 GitHub 不同,實際權限應依自動權杖、PAT 範圍、組織權限和分支保護規則確認。使用 OIDC 的工作流程也需要另外調整;Forgejo 使用的是 enable-openid-connect 設定。
Docker 工作流程要同時遷移建置環境和發布目標
原工作流程將映像檔發布到 GHCR,驗證通常使用 GitHub 使用者帳號和 GITHUB_TOKEN。如果目標改為 CodeFloe 容器映像檔儲存庫,就需要調整映像檔位址和登入憑證。
可以在工作流程中明確宣告映像檔路徑:
映像檔路徑應使用小寫。如果要發布到特定組織,也不能繼續直接使用 ${{ github.repository }},因為程式碼儲存庫的擁有者與映像檔所屬組織不一定相同。
建置步驟可以保留 Docker 官方 Actions:
這裡明確初始化 Buildx,並關閉依賴 GitHub 專屬服務的建置紀錄上傳和摘要。原設定若使用了 type=gha 快取,也應重新確認目標服務是否支援,再決定改用 registry 快取或其他方案。
上述 YAML 是工作流程片段,需要與前面的 runner、相依套件準備和 checkout 步驟搭配使用;專案特有的建置參數也需要自行保留。
映像檔是否私有由擁有者決定
遷移容器映像檔儲存庫時,還需要確認存取權限。Forgejo 的套件屬於使用者或組織,不屬於程式碼儲存庫。
因此,由私有程式碼儲存庫建置的映像檔不會自動成為私有映像檔。依照 Forgejo 目前的文件,公開組織下的套件可供公開讀取,私有組織下的套件則只允許組織成員讀取。
如果希望程式碼維持在原本的位置,映像檔則單獨設為私有,可以建立專用的私有組織,並發布到:
發布用帳號需要具備該組織的套件寫入權限,PAT 必須允許存取私有資源,不能選擇僅限公開資源的範圍。部署伺服器則需要先用具有讀取權限的組織成員帳號登入,再拉取映像檔:
將新映像檔發布到私有組織,也不會自動改變舊位址下已發布的套件,舊套件及部署時的引用需要另行處理。
同步工作流程適合直接檢查 Git 操作
原本的同步流程使用第三方 Action 拉取 GitHub 上游,再透過另一個 Action 執行 rebase。這類 Action 可能會寫死目標平台、儲存庫位址或驗證方式。
當流程主要由 Git 操作組成時,直接使用 Git 指令通常更容易檢查遷移後的行為。本次保留的流程是:
這次改寫特別處理了幾個問題:
最後一項透過明確指定 lease 和原子推送實現:
這需要在操作前記錄遠端分支的提交雜湊值。遠端支援原子推送時,兩個分支可以一起更新;如果執行期間分支發生變化,推送會拒絕覆寫。
rebase 會改變提交歷史,應依專案原有的協作方式判斷是否適合使用,並確認分支保護規則允許相應更新。
部署工作流程需要驗證指令的實際結果
EdgeOne 部署保留了原本的作業步驟:將 main 合併到部署用調整分支,更新子模組,推送分支,再建置並部署。
這裡的遷移重點是固定執行環境、使用正確憑證,以及可靠地判斷部署結果。例如:
pipefail 可以避免部署指令失敗後,其結束狀態被成功執行的 tee 掩蓋。
取得 JSON 輸出後,應解析結構化結果,檢查 status 和存取位址,而不是只靠字串搜尋判斷是否成功。EdgeOne 回傳的存取 URL 可能帶有必要的查詢參數,寫入日誌和任務摘要時應完整保留。
至於 concurrency,則需要確認目標 Forgejo 版本是否支援。本次分別為同步、映像檔發布和部署設定了並行群組,並設為 cancel-in-progress: false,避免新啟動的工作流程隨意中斷正在進行的發布。
最後要驗證的是行為,而不只是 YAML
遷移後可以分三個層次驗證。
第一層是靜態檢查:YAML 能否解析、欄位是否正確、Shell 是否有語法錯誤,以及 Action URL 是否明確。這一層能發現設定錯誤,但不能證明驗證和網路存取正常。
第二層是腳本行為驗證。本次在暫存 Git 儲存庫中驗證了正常同步、重複執行、測試模式、合併衝突、rebase 衝突和並行更新保護;部署腳本則涵蓋成功結果、錯誤結果、CLI 以非零狀態碼結束和無效 JSON。
第三層是在目標平台實際執行。先透過 workflow_dispatch 驗證 runner 和憑證,再檢查實際的映像檔發布、私有映像檔拉取,以及推送 main 後能否觸發完整流程。本文記錄的遷移已完成前兩層,第三層仍需透過目標平台的實際執行紀錄確認。
排查時,可以根據現象縮小範圍:
現象
優先檢查
工作流程沒有出現
Actions 是否啟用、目錄位置、預設分支上的檔案
任務一直排隊
runner 標籤和架構是否相符
Action 下載失敗
完整 URL、版本參照和網路存取
提示缺少 Node.js 或 bash
job 容器的執行環境
無法連接 Docker daemon
是否使用平台支援的 Docker runner
Registry 登入成功但推送失敗
PAT 範圍、映像檔所屬組織的權限和命名空間
同步推送後沒有觸發部署
推送是否使用了自動任務權杖
私有儲存庫對應的映像檔仍可匿名拉取
映像檔所屬使用者或組織的可見性
這次遷移得到的經驗是:保留可以沿用的 YAML 和建置步驟,同時逐一確認它們依賴的平台功能。目錄、runner、驗證、映像檔儲存庫和下游觸發都確認清楚後,原本在 GitHub 上執行的自動化流程,才能在 Forgejo 上如預期運作。
參考資料