參與貢獻
如何回報問題、提出建議,或修改 ThirtyFile 程式碼。
所有參與者都須遵守行為準則。
問題與建議
- 建立 Issue,選擇合適的表單:回報問題、Suggest an idea、Report an accessibility barrier、Improve the guides 或 Improve the code。表單會詢問協助處理所需的資訊。
- 先檢視已有 Issue。如果已有相同問題,請補充到該 Issue,而非重複建立。
修改程式碼
禁止直接推送到 main。每項更改都透過獨立分支的 Pull Request 提交。
- 從 Issue 開始。大於小修復的工作,先在 Issue 中討論並確認方案。
- 從
main建立分支,按用途命名:分支 用途 feat/share-link-editing新增功能 fix/upload-resume問題修復 docs/backup-guide網站與指南 chore/update-actions工具、建置與相依套件 - 完成更改,執行下方檢查。
- 建立 Pull Request。標題用清晰語言說明改動,並新增一個標籤。在說明中寫
Closes #123,合併後即可關閉對應 Issue。 - 等待檢查。輕量的 Checks passed 檢查必須通過才能合併。
- 合併。Pull Request 在
main上壓縮為一個提交,隨後刪除分支。
檢查
建立 Pull Request 前,請使用統一腳本在本機執行完整檢查。發布和手動完整驗證也會執行這些檢查;自動 Pull Request 檢查更輕量。
scripts/check.sh
| 部分 | 檢查內容 |
|---|---|
scripts/check.sh quick | 自動 Pull Request 檢查:前端格式、翻譯、模組邊界、端到端測試結構、類型和 lint;Rust 格式;遷移編號及已發布遷移保持不變;網站連結。不執行單元/瀏覽器測試、Rust 編譯或映像建置 |
scripts/check.sh web | 介面:按鎖定檔安裝相依套件、格式(pnpm format:check)、翻譯(node scripts/check-i18n.mjs)、確保 web/src/ooxml 的 Office 程式碼不匯入應用程式其他模組(node scripts/check-boundaries.mjs)、確保端到端測試沒有固定等待且名稱包含隨機部分(node scripts/check-e2e.mjs)、類型、lint 和單元測試。使用 scripts/check.sh web --coverage 時(與 GitHub 一樣),覆蓋率低於 web/vitest.config.ts 中的門檻也會失敗 |
scripts/check.sh server | 伺服器:格式(cargo fmt --check)、cargo test,以及將警告視為錯誤的 cargo clippy |
scripts/check.sh e2e | 端到端測試:透過真實瀏覽器(Playwright)對從倉庫建置的伺服器執行登入、上傳和預覽。多個測試並行執行(GitHub 上為 4 個),因此每個測試使用獨立資料夾,名稱含隨機部分,操作後等待伺服器回應而非固定時間;web/tests/e2e/helpers.ts 提供這些輔助功能。首次執行前,用 cd web && pnpm exec playwright install chromium 安裝瀏覽器 |
scripts/check.sh site | 網站:每種語言都具有全部翻譯頁面及相互對應的語言連結,站內連結和錨點有效(node scripts/check-site.mjs)。僅需要 Node,修改網站時也會執行 |
Windows 上請在 Git Bash 中執行。GitHub 完整驗證還會檢查相依套件的已知安全問題(cargo deny 和 pnpm audit);伺服器測試與端到端測試合計必須覆蓋至少 90% 的伺服器程式碼行(cargo llvm-cov,門檻在 .github/workflows/build.yml)。
程式碼由工具格式化,未符合格式時檢查會失敗。提交前請格式化:
cd server && cargo fmt
cd web && pnpm format
伺服器使用 rustfmt(設定在 server/rustfmt.toml),介面使用 oxfmt(設定在 web/.oxfmtrc.json;格式化 web/src、web/tests 和 web/scripts)。編輯器安裝 rustfmt 或 oxfmt 擴充套件後可按同樣設定在儲存時格式化。手工排版、每行多項的表格可在上方加 // oxfmt-ignore 保持版面。web/src/lib/i18n/ 中的詞典不格式化,保持每行一個條目。
僅調整格式的提交列在 .git-blame-ignore-revs。GitHub blame 檢視會跳過這些提交;如需本機 git blame 也跳過,在複製倉庫中執行一次 git config blame.ignoreRevsFile .git-blame-ignore-revs。
- 程式碼、註解和指南源文使用英文。
- 介面文字在程式碼中使用英文,譯文位於
web/src/lib/i18n/,每種語言一個資料夾,檔案名稱保持一致。繁體中文(zh-TW)、簡體中文(zh-CN)和日文(ja)均為必需語言:新增文字須按下方術語表補齊三種譯文。node scripts/check-i18n.mjs檢查所有語言:必需語言缺項,或保留程式碼已不再使用的條目時會失敗;其他語言僅報告這些問題及佔位翻譯數量。語言列入腳本的COMPLETE後即為必需語言,語言切換器提供的語言也必須完整。可用--require <language>檢視新語言尚缺哪些內容。 - 伺服器自行產生的郵件文字,以英文定義在
server/src/i18n/texts.rs,各語言譯文位於旁邊的檔案(zh_tw.rs、zh_cn.rs、ja.rs)。缺少譯文時使用英文。伺服器測試會檢查texts.rs中列入COMPLETE,或語言切換器提供的語言;缺少文字或{parameters}與英文不一致時會失敗。 - 行為改變時,同步更新
site/docs/中描述該行為的指南。 - 0.4.0 的資料庫結構已凍結,確保舊版本建立的資料繼續有效。結構修改必須新增
server/migrations/0002_<name>.sql及後續編號的遷移檔案,以升級 0.4.0 資料庫。禁止修改0001_init.sql和此前版本已發布的遷移檔案,檢查會阻止這種修改。 - 網頁應用程式的 API 型別(
web/src/api/types.ts)是手寫的。伺服器有一項測試把主要回應的結構記錄在web/tests/contract/shapes.json,結構一改就會失敗:在server/執行THIRTYFILE_UPDATE_SHAPES=1 cargo test api_shapes,再修改型別直到pnpm typecheck通過。 - 會更改使用者檔案的邏輯(公式、活頁簿儲存、文字編碼)須在
web/tests/unit/中新增單元測試。
每個 Pull Request 都執行上述輕量檢查。完整測試與映像建置在正式發布和預發布前執行,也可在 Actions › Build › Run workflow 手動執行;手動驗證不發布任何內容。發布前,兩種架構的映像都會使用 compose.yaml 在最新已發布版本的資料上啟動。CodeQL 在合併後、每週及發布前掃描 main。合併到 main 不發布任何內容,網站也不發布:指南隨版本發布,以描述使用者實際可安裝的功能。對目前已發布版本也正確的指南修復可手動發布:在 Actions › Website › Run workflow 中選擇 main 為要發布的分支或標籤。
其他語言的網站
首頁與全部 16 篇指南都提供英文、繁體中文、簡體中文與日文。每個語言都有相同的 17 個頁面:
| 頁面 | 英文 | 其他語言 |
|---|---|---|
| 首頁 | site/index.html | site/<language>/index.html |
| 安裝 | site/docs/index.html | site/<language>/docs/index.html |
| 所有其他指南 | site/docs/<guide>.html | site/<language>/docs/<guide>.html |
指南選單、相關連結、上一篇/下一篇與章節清單都保持讀者選擇的語言。切換語言時仍留在同一篇指南;啟用 JavaScript 時也保留目前章節。README 也提供翻譯:README.md 旁有 README.zh-TW.md、README.zh-CN.md 與 README.ja.md,各自連到該語言的網站。
- 修改翻譯頁面時,必須在同一個 Pull Request 更新所有語言。如果不會其中一種語言,請在 Pull Request 說明,維護者會安排其他人協助。
- 每個版本都有
<html lang>、獨立標題與描述,以及指向所有版本(含自身)的<link rel="alternate" hreflang>。語言切換器、指南選單與章節清單直接寫在每個頁面中,沒有 JavaScript 也能使用。所有語言的章節 ID 與指令/設定範例必須完全一致。 - 語言與所有頁面列在
site/assets/site.js頂部的LANGUAGES與TRANSLATED中,該檔案也包含選單與頁尾翻譯。變更導覽或指南標題後,請執行node scripts/update-site-navigation.mjs更新靜態選單與章節清單。scripts/check.sh site會在翻譯遺漏、中繼資料或語言切換器錯誤、章節遺失、程式區塊變更、連結失效或意外連到其他語言時失敗。新增頁面必須在同一個 Pull Request 補齊所有支援語言。執行node --test scripts/check-site.test.mjs可測試檢查器;安裝前端的 Playwright 相依套件與 Chromium 後,node scripts/check-site-browser.mjs <scratch-directory>會檢查瀏覽器實際呈現的頁面、語言與章節切換、手機版面,以及沒有 JavaScript 時的導覽,並將截圖保存於網站目錄之外。 - 用詞遵循術語表(
web/src/lib/i18n/glossary.md),與介面翻譯一致。簡體中文使用中國大陸的習慣用語,不只是繁體字轉換;日文句子使用です・ます,並採用 Windows 檔案總管與 Finder 的術語。 - 首頁主要截圖依各語言分別拍攝,使用本機實例與範例資料,1280 × 720、2 倍縮放,儲存為 WebP(
site/assets/files-light-<language>.webp與files-dark-<language>.webp)。其他截圖保留英文。
標籤
| 標籤 | 版本說明中的分類 |
|---|---|
enhancement | 新功能 |
bug | 修復 |
performance | 效能提升 |
accessibility | 更易使用 |
documentation | 指南與網站 |
dependencies | 相依套件更新 |
maintenance | 維護 |
發布版本
正式映像同時發布到 ghcr.io/thirtyfile/thirtyfile 和 docker.io/thirtyfile/thirtyfile。首次向 Docker Hub 發布前,在 Settings › Secrets and variables › Actions 中新增 Actions variable DOCKERHUB_USERNAME 和 secret DOCKERHUB_TOKEN。使用可讀寫該倉庫的 Docker Hub access token。發布流程會在掃描與建置前檢查認證資訊,按 digest 複製已驗證的映像,並在發布 GitHub release 前驗證每個 Docker Hub 標籤。
合併後的更改累積在 main,由維護者決定何時發布。發布須手動啟動:在 GitHub 開啟 Actions › Release › Run workflow,保留 main,輸入新版本編號,例如 1.2.3;預發布使用 1.2.3-rc.1。也可執行:
gh workflow run release.yml -f version=1.2.3
流程對 main 執行 CodeQL 掃描、測試,建置並啟動 amd64 與 arm64 映像。全部通過後才推送尚未附加標籤的映像。接著依序:從映像提取兩種架構的伺服器程式,與校驗碼、授權聲明和指向版本系列的 compose.yaml 建立草稿 release(1.0.0 之前為 :1.2,之後為 :1);不重新建置,給映像新增 1.2.3、1.2、1(從 1.0.0 起)及 latest 標籤;發布 release,建立 v1.2.3 標籤,說明由上次發布以來合併的 Pull Request 產生;最後從該標籤發布網站。如果掃描發現未關閉的 high 或 critical 警示,或者測試或映像失敗,不會推送、新增標籤或發布。修復警示,或在不適用時從 Security › Code scanning 中關閉警示,再次執行發布。後續步驟失敗時,用相同版本編號重試,會發布已標記為 1.2.3 的映像,而非重新建置。版本編號必須比上次發布更新。以 v 開頭的標籤不能移動或刪除。
含 - 的版本編號,例如 1.2.3-rc.1,為預發布:映像僅新增 1.2.3-rc.1 標籤,GitHub 將其標為預發布,使用者必須主動選擇才會獲得;預發布不會發布網站。預發布驗證通過且之後沒有合併新提交時,可從同一提交發布 1.2.3:流程直接為預發布映像新增標籤,不重新建置,確保發布的就是已試用的內容(映像版本標籤仍顯示預發布版本)。
| 版本位 | 遞增時機 |
|---|---|
第一位(2.0.0) | 修改或移除使用者依賴的行為 |
第二位(1.3.0) | 新增功能 |
第三位(1.2.4) | 僅修復問題 |
複製已有版本時,在 Actions › Mirror a release to Docker Hub › Run workflow 中選擇 main,填寫已發布版本,例如 0.6.0。流程先驗證 Git 標籤、映像 revision 和已簽名的 GHCR 來源證明,再複製映像。僅當 GHCR 對應的版本系列、主版本或 latest 標籤目前指向同一映像時,才更新該標籤;映像舊版本不會覆蓋更新版本。已有的精確版本標籤必須與來源 digest 一致,否則流程停止。內容一致的複製可安全重試,不會重新建置映像。
授權條款
ThirtyFile 採用 Apache License 2.0,貢獻內容遵循相同條款。
相依套件須採用寬鬆授權條款:Rust 相依套件按 server/deny.toml 清單檢查,server/about.toml 使用相同清單;npm 套件按 web/scripts/third-party-notices.mjs 中相同清單(另加字型授權條款 OFL-1.1)檢查,兩者均有測試。映像建置會把所有 crate、npm 套件、musl、憑證頒發機構和時區資料庫的授權聲明彙總為 THIRD-PARTY-NOTICES;出現清單之外的授權條款時建置失敗。