From a061ea451d66e7ade2cabbdf93a95bc5d95801b3 Mon Sep 17 00:00:00 2001 From: HSU-YU-MING Date: Sat, 8 Aug 2026 09:34:17 -0500 Subject: [PATCH] =?UTF-8?q?docs:=20=E8=A3=9C=E4=B8=8A=20RELEASING.md=20?= =?UTF-8?q?=E8=88=87=20ROADMAP.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 另外三個姊妹 repo 都有這兩份,只有這裡沒有。 RELEASING.md —— 這個 repo 發版很稀疏(7 月 1.0、8 月 1.1),流程會忘;而且今天才剛 變過(多了自動建 GitHub Release)。特別寫進去的兩件事: - 版號只從 tag 來,不需要事先改任何檔案 - **抬高相依樓地板 = major**。README 承諾支援 EF Core 8+,往上抬會讓 EF 8 的使用者 直接裝不起來;analyzer 的 Roslyn 版本同理,它決定消費端需要的最低 VS/SDK 世代 ROADMAP.md —— 不是憑空規劃,是把 README 的 Limitations 拆開。那一節原本混了兩種東西: 「這是泛型主鍵的必然代價,你得認了」(如 LabelHit.EntityId 是 object)和「這個以後會有」 (UNION ALL 優化、多租戶、每父層唯一命名 —— 最後一項自己就寫著「屬 v2 範疇」)。 讀者分不出來。前者留在 README,後者收進 ROADMAP,每一條都標明觸發條件。 順帶修正 tests csproj 對 CornhsuEfVersion 的註解。先前(#11)把 8.0.11 描述成 「Npgsql 訂的礙事天花板」,框錯了方向 —— 它真正的意義是「必須等於 src 的樓地板」, 因為那個預設值就是在測我們對外承諾的最低版本。Npgsql 的上限只是剛好重合在同一個數字, 而它真正會咬人的時機是「哪天要抬高 src 樓地板」。 Co-Authored-By: Claude Opus 5 --- RELEASING.md | 61 +++++++++++++++++++ ROADMAP.md | 44 +++++++++++++ .../Cornhsu.Labeling.Tests.csproj | 16 +++-- 3 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 RELEASING.md create mode 100644 ROADMAP.md diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000..5840699 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,61 @@ +# Releasing(照 Parity 的形狀) + +## 流程 + +1. 更新 `CHANGELOG.md`:新增版本段落。**Release notes 直接取自這一節**, + 所以這裡寫得夠不夠好,就等於 GitHub Releases 頁上的品質。 +2. 推 tag: + +```bash +git tag v1.2.0 +git push origin v1.2.0 +``` + +3. `.github/workflows/release.yml` 接手:從 tag 導出版本 → restore → build → test → + `dotnet pack` → 以 **NuGet Trusted Publishing**(OIDC,無長期 API key)發佈 + `Cornhsu.Labeling` 與 `Cornhsu.Labeling.EntityFrameworkCore` → **自動建 GitHub Release** + +> 版號**只從 tag 來**。csproj 裡沒有寫死的 ``,不需要(也不該)事先改任何檔案的版號。 + +## 版本規則 + +自 1.0.0 起 API 穩定: + +- **major**:公開 API 的破壞性變更、或抬高相依樓地板(見下) +- **minor**:新增 API、或對外可見文字的改變(例外訊息、analyzer 診斷 —— 有人在斷言這些) +- **patch**:修正,對外行為不變 + +## 抬高相依樓地板 = major + +README 承諾「支援 EF Core 8+,消費端用 9/10 會自動 unify」。把 +`src/Cornhsu.Labeling.EntityFrameworkCore` 的 `Microsoft.EntityFrameworkCore.Relational` +往上抬,會讓還在 EF 8 的使用者直接裝不起來 —— 那是破壞性變更。 + +同理,`Cornhsu.Labeling.Analyzers` 的 `Microsoft.CodeAnalysis.CSharp` 版本 +決定了消費端需要的最低 VS/SDK 世代(目前 4.8 = VS2022 17.8 / SDK 8,相容範圍最大)。 + +⚠ 真的要抬樓地板時,記得 `tests/Cornhsu.Labeling.Tests.csproj` 的 `CornhsuEfVersion` +預設值必須跟著改成同一個版本 —— 它的意義就是「測我們對外承諾的最低版本」。 +但那個值目前**卡在 8.0.11**:它同時餵三個 provider,而 Npgsql 的 EF 8 線只到 8.0.11 +(Microsoft 走到 8.0.29)。詳見該 csproj 的註解。 + +dependabot 已對這幾項設 `ignore`,不會自動提出 —— 抬樓地板要有意識地改 csproj + +README + CHANGELOG,不是按 merge。 + +## CI 矩陣 + +每次 push 都跑:三資料庫(SQLite / SQL Server / PostgreSQL)× EF Core 8 / 9 / 10。 +EF 9/10 是**真的引用新版 EF 跑同一套測試**,不是只換 SDK: + +```bash +dotnet test tests/Cornhsu.Labeling.Tests -p:CornhsuTestTfm=net10.0 -p:CornhsuEfVersion=10.0.* +``` + +`samples/MinimalConsole` 也在 CI 跑 —— 它是「抽象是否成立」的哨兵,不只是示範。 + +## 首次發佈前的一次性設定(已完成) + +- NuGet.org:兩個套件都設定 Trusted Publishing + (repo `HSU-YU-MING/cornhsu-labeling`、workflow `release.yml`) +- `Cornhsu.*` 前綴已獲 NuGet 官方保留 +- workflow 已宣告 `id-token: write`(OIDC)與 `contents: write`(建 Release) diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..36cee04 --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,44 @@ +# Roadmap + +「已完成」看 [README](README.md) 與 [CHANGELOG](CHANGELOG.md)。這裡只記**還沒做的**。 + +這份文件存在的理由:README 的 Limitations 混了兩種東西 —— 「這是泛型主鍵的必然代價, +你得認了」和「這個以後會有」。讀者分不出來。前者留在 README,後者收在這裡。 + +## 明文不做(不是遺漏) + +- **`LabelHit.EntityId` 改成強型別**。跨型別查詢的命中本來就可能來自不同主鍵型別 + (`Note` 是 Guid、`TodoItem` 是 int),`object` 是泛型主鍵的必然代價, + 不是偷懶。要強型別用 `EntityIdAs()`。 +- **`Label` 加業務欄位**(標籤型別、模組/租戶隔離、權限…)。套件無法理解、 + 也無法替你把關這些概念,加了只是假裝支援。用 1:1 伴生表,見 README「擴充 Label」。 + +## 有觸發條件才做 + +- **跨型別查詢合併成 `UNION ALL`**。現在是「每個註冊型別一次查詢」的樸素策略。 + benchmark 顯示 5 型別 × 10,000 筆、12 萬連結時仍在 ~18 ms —— 這個規模下不值得 + 換複雜度。**觸發條件**:有人回報實測瓶頸,或註冊型別數成長到兩位數。 +- **多租戶:各租戶不同的可標記型別**。EF Core 的 model cache 以 DbContext 型別為 key, + 要支援得自訂 `IModelCacheKeyFactory`。**觸發條件**:出現真實需求 —— + 這會把 registry 從「全 App 單例」變成「每租戶一份」,是核心假設的改動,不能為想像中的 + 使用者先做。 +- **Analyzer 的 code fix**。`CHSU001` 現在只警告不修。技術上卡在兩點:它是 + `CompilationEnd` 診斷(要完整建置才出現,IDE 的即時分析不產生,燈泡幾乎不會亮), + 而且修法要動到「另一個檔案的 `AddLabeling` lambda」,跨檔案的 code fix 既脆弱又難預測。 + `CHSU002` 倒是可以做(純本地改寫:讀 `Id` 型別、把 `ILabelable` 改成 `ILabelable`), + 但它只會在每個型別上發生一次,而診斷訊息已經明說該怎麼改。 + **觸發條件**:有人回報訊息不夠清楚。目前的解法是 + [docs/analyzer-rules.md](docs/analyzer-rules.md) 加上 `helpLinkUri`。 + +## v2 範疇(會破壞 API) + +- **標籤名稱改為「每父層唯一」**。現在是全域唯一,含跨階層 ——「工作/雜項」和 + 「生活/雜項」不能各有一個「雜項」。這是刻意取捨:整個 API 以名稱定址 + (`AttachAsync`、`FindByLabelAsync` 都吃名稱字串),允許同名會讓所有名稱定址的呼叫變歧義。 + 真要支援,勢必伴隨路徑定址(`"生活/雜項"`)的 API 改版 —— 那是 major。 + 在那之前,把限定詞放進名稱本身(如「生活·雜項」)。 + +## 1.0 之後的維護原則 + +API 已凍結。相依樓地板(EF Core 8、Roslyn 4.8)也是對外承諾的一部分, +抬高它等同破壞性變更 —— 見 [RELEASING.md](RELEASING.md)。 diff --git a/tests/Cornhsu.Labeling.Tests/Cornhsu.Labeling.Tests.csproj b/tests/Cornhsu.Labeling.Tests/Cornhsu.Labeling.Tests.csproj index 7ec5fd8..974cd47 100644 --- a/tests/Cornhsu.Labeling.Tests/Cornhsu.Labeling.Tests.csproj +++ b/tests/Cornhsu.Labeling.Tests/Cornhsu.Labeling.Tests.csproj @@ -3,11 +3,17 @@ net8.0 - + 8.0.11 8.0.1