feat(git): PR 目標分支改走階梯推導,既有 PR 改為校準不重開 #12

Merged
jiantw83 merged 5 commits from feat/sdlc-flow-rules/main into develop 2026-08-27 03:39:40 +00:00
Member

PR 描述

摘要

  • 需求描述:把功能主幹 feat/sdlc-flow-rules/main 累積的內容整批推上 develop。本存取庫負責使用者 15 條規則第一群「SDLC 執行流程」裡的 R3 與 R2 的落地:R3 的分支階梯不能只寫在準則裡靠模型自律,要由 base-branch.sh 在程式層推導出來;R2 的「每次 commit 後校準 PR」則要讓 jsc-git:pr 遇到既有 PR 時改成比對三項、有差才改,而不是關掉重開。
  • 計畫名稱:無
  • 計畫頁:無
  • 分析頁:無

本 PR 併入 5 個 commit,來自已合併的子功能 PR plugins/git#11。

變更內容

檔案 為什麼改
tools/base-branch.sh 新增 --derive 模式,從分支名推出唯一合法的上一階基底,並在功能主幹不存在時自動建立。階梯寫在準則裡是給人看的,寫在這裡才擋得住越級
skills/pr/SKILL.md 目標分支改走階梯推導;既有 PR 從「關掉重開」改成校準標題、描述、上層 PR 依賴三項
skills/commit/SKILL.md 加上校準觸發點:每次 commit 之後就去校準對應的 PR,這是 R2 的入口
README.md 補上 PR 階梯與兩支技能的新行為
plugin.json、.claude-plugin/plugin.json、.codex-plugin/plugin.json 三份 manifest 版本同步升到 0.0.8

設計重點

  • --derive 只推導唯一合法的上一階。推不出來就以退出碼 7 中止,由呼叫端問使用者,不猜、也不退回 develop。退回 develop 就是預設允許越級,正是這支腳本要擋的事。
  • 功能主幹 {類型}/{功能}/main 不在 origin 時,自動以 origin/develop 為起點建立並推上去,再把建立了哪一條分支印到 stderr。決策紀錄見 wiki QUESTION_FB8DF0B5 的 2026-08-27 那一節 Q3。自動建立配上明確回報,比每個新功能都多一輪問答來得省事。
  • 原有的「呼叫方傳入的分支最優先」模式保留不動,兩種模式並存。判斷「有沒有傳」看參數個數、不看參數內容:呼叫方寫 base-branch.sh "$SOURCE_BRANCH" 而變數沒設定時,那是空字串、不是沒傳;當成沒傳就會悄悄退回 develop,把單一工作包直接併進 develop。
  • 退出碼分得細,呼叫端才有辦法分流:2 參數過多、3 抓不到遠端、4 指定的分支不在遠端、5 develop 與 main 與 master 都不在遠端、6 傳入空字串、7 推不出唯一合法基底、8 推導出的基底不在遠端又不能自動建立、9 自動建立功能主幹失敗。
  • 既有 PR 的校準採「三項全查,有差才改」(Q4):比對標題、描述、上層 PR 依賴,內容真的變了才呼叫 API 更新。每次 commit 都重寫描述會產生一連串更新通知,只補描述又會讓標題與依賴逐漸過時。
  • 校準走 jsc-gitea 的 gitea.sh pr-get 與 pr-edit,不自行拼 API。
  • 分支名只允許 ASCII,中文簡述先交給同目錄的 slugify.sh 轉成 slug,base-branch.sh 本身不接受非 ASCII 分支名。

測試結果

  • 子功能 PR plugins/git#11 已完成該層的驗證並合併,本 PR 不再重跑一次。
  • 主幹整合後複驗:sh -n tools/base-branch.sh 通過。
  • 主幹整合後複驗:jsc-meta/tools/ste100-lint.sh 掃整個存取庫全綠。
  • 自動建立功能主幹已在真實環境驗證:本批七個存取庫的 feat/sdlc-flow-rules/main 全部由 base-branch.sh --derive 自動從 develop 建立並推上 origin,七次都印出建立訊息、退出碼 0;主幹已存在時再跑一次只印分支名,不重複建立。

前置 Push Request

  • 本 PR 的 PR 校準會用到 jsc-gitea 的 gitea.sh pr-get 與 pr-edit。該依賴已隨 plugins/gitea#22 合併進 gitea 的功能主幹,沒有未結清的前置 PR,不需要掛 gitea.sh pr-depend。
# PR 描述 ## 摘要 - 需求描述:把功能主幹 `feat/sdlc-flow-rules/main` 累積的內容整批推上 `develop`。本存取庫負責使用者 15 條規則第一群「SDLC 執行流程」裡的 R3 與 R2 的落地:R3 的分支階梯不能只寫在準則裡靠模型自律,要由 `base-branch.sh` 在程式層推導出來;R2 的「每次 commit 後校準 PR」則要讓 `jsc-git:pr` 遇到既有 PR 時改成比對三項、有差才改,而不是關掉重開。 - 計畫名稱:無 - 計畫頁:無 - 分析頁:無 本 PR 併入 5 個 commit,來自已合併的子功能 PR [plugins/git#11](https://gitea.jsc.idv.tw/plugins/git/pulls/11)。 ## 變更內容 | 檔案 | 為什麼改 | | --- | --- | | `tools/base-branch.sh` | 新增 `--derive` 模式,從分支名推出唯一合法的上一階基底,並在功能主幹不存在時自動建立。階梯寫在準則裡是給人看的,寫在這裡才擋得住越級 | | `skills/pr/SKILL.md` | 目標分支改走階梯推導;既有 PR 從「關掉重開」改成校準標題、描述、上層 PR 依賴三項 | | `skills/commit/SKILL.md` | 加上校準觸發點:每次 commit 之後就去校準對應的 PR,這是 R2 的入口 | | `README.md` | 補上 PR 階梯與兩支技能的新行為 | | `plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json` | 三份 manifest 版本同步升到 `0.0.8` | ## 設計重點 - `--derive` 只推導**唯一合法**的上一階。推不出來就以退出碼 `7` 中止,由呼叫端問使用者,不猜、也不退回 `develop`。退回 `develop` 就是預設允許越級,正是這支腳本要擋的事。 - 功能主幹 `{類型}/{功能}/main` 不在 origin 時,自動以 `origin/develop` 為起點建立並推上去,再把建立了哪一條分支印到 stderr。決策紀錄見 wiki [QUESTION_FB8DF0B5](https://gitea.jsc.idv.tw/knowledges/QUESTION/wiki/QUESTION_FB8DF0B5) 的 2026-08-27 那一節 Q3。自動建立配上明確回報,比每個新功能都多一輪問答來得省事。 - 原有的「呼叫方傳入的分支最優先」模式保留不動,兩種模式並存。判斷「有沒有傳」看參數個數、不看參數內容:呼叫方寫 `base-branch.sh "$SOURCE_BRANCH"` 而變數沒設定時,那是空字串、不是沒傳;當成沒傳就會悄悄退回 `develop`,把單一工作包直接併進 `develop`。 - 退出碼分得細,呼叫端才有辦法分流:`2` 參數過多、`3` 抓不到遠端、`4` 指定的分支不在遠端、`5` `develop` 與 `main` 與 `master` 都不在遠端、`6` 傳入空字串、`7` 推不出唯一合法基底、`8` 推導出的基底不在遠端又不能自動建立、`9` 自動建立功能主幹失敗。 - 既有 PR 的校準採「**三項全查,有差才改**」(Q4):比對標題、描述、上層 PR 依賴,內容真的變了才呼叫 API 更新。每次 commit 都重寫描述會產生一連串更新通知,只補描述又會讓標題與依賴逐漸過時。 - 校準走 `jsc-gitea` 的 `gitea.sh pr-get` 與 `pr-edit`,不自行拼 API。 - 分支名只允許 ASCII,中文簡述先交給同目錄的 `slugify.sh` 轉成 slug,`base-branch.sh` 本身不接受非 ASCII 分支名。 ## 測試結果 - 子功能 PR [plugins/git#11](https://gitea.jsc.idv.tw/plugins/git/pulls/11) 已完成該層的驗證並合併,本 PR 不再重跑一次。 - 主幹整合後複驗:`sh -n tools/base-branch.sh` 通過。 - 主幹整合後複驗:`jsc-meta/tools/ste100-lint.sh` 掃整個存取庫全綠。 - 自動建立功能主幹已在真實環境驗證:本批七個存取庫的 `feat/sdlc-flow-rules/main` 全部由 `base-branch.sh --derive` 自動從 `develop` 建立並推上 origin,七次都印出建立訊息、退出碼 0;主幹已存在時再跑一次只印分支名,不重複建立。 ## 前置 Push Request - 本 PR 的 PR 校準會用到 `jsc-gitea` 的 `gitea.sh pr-get` 與 `pr-edit`。該依賴已隨 [plugins/gitea#22](https://gitea.jsc.idv.tw/plugins/gitea/pulls/22) 合併進 gitea 的功能主幹,沒有未結清的前置 PR,不需要掛 `gitea.sh pr-depend`。
jiantw83 added 5 commits 2026-08-27 03:38:56 +00:00
What:`tools/base-branch.sh` 新增 `--derive [分支]` 模式,從分支名推出唯一合法的上一階基底。`feat` 這一類走 `{類型}/{功能}/{子功能}` → `{類型}/{功能}/main` → `develop` → `master`,`fix` 走 `fix/{修改}` → `develop` → `master`。新增退出碼 `7`(推不出唯一合法基底)、`8`(推導出的基底不在遠端又不能自動建立)、`9`(自動建立功能主幹失敗)。既有的呼叫方模式一字未改。

Why:PR 階梯禁止越級,但基底原本靠呼叫端自己挑,挑錯就是把一個子功能直接併進 `develop`,中間那層功能主幹整個被跳過。判斷寫進程式,越級就不會發生在「這次剛好沒注意」的時候。

How:`{子功能}` 可以多層,推導一律把最後一段換成 `main`。推不出唯一合法基底就中止並回 `7`,由呼叫端問使用者,不猜、也不退回 `develop`——退回 `develop` 正是這支腳本要擋的那件事。功能主幹不在 origin 時,直接把 `origin/develop` 推成新分支自動補一條,不動本機工作區,再把建立了哪一條分支印到 stderr。分支名只收 ASCII 小寫、數字、連字號與斜線,中文簡述請先過 `tools/slugify.sh`。

Who:`jsc-git:pr` 決定 PR base 的那一步,以及所有經由它開 PR 的技能。
What:`pr` 技能新增「PR ladder」一節與階梯形狀的分支命名(`fix` 叫一次 `slugify.sh`,其餘型別叫兩次組出 `{類型}/{功能}/{子功能}`),base 一律由 `base-branch.sh --derive` 推導;新增步驟 6 查目標分支有沒有開啟中的 PR,有就跳到新的步驟 9 比對標題、描述、前置 PR 依賴三項,只有不一樣的那幾項才送 API。`commit` 技能新增步驟 5:認可完成後,目前分支已有 PR 就交給 `pr` 校準。

Why:越級開 PR 與「同一條分支重開第二支 PR」是同一個病灶的兩面——base 與 PR 現況都靠人記。改成先推導、先比對之後,base 由腳本決定,PR 只在真的有差時才更新。

How:呼叫方傳入的 base 仍然照收,但要與推導結果一致;不一致就當成越級擋下,說明正確階梯再問使用者,不會悄悄改目標。校準走 `jsc-gitea` 的 `pr-get` 讀現況、`pr-edit` 一次帶標題與描述、`pr-depend` 補依賴;三項都相同就什麼都不做——每一次多餘的編修都會通知所有審查者,安靜才是對的結果。

Who:`jsc-git:pr` 與 `jsc-git:commit` 兩支技能,以及呼叫它們的 `jsc-sdlc:implement`、`jsc-sdlc:maintain` 與 `jsc-meta` 各技能。
What:README 新增「PR 階梯」一節(兩種型別的階梯表、多層子功能的推導方式、推不出就回 `7` 中止、功能主幹自動建立),工具表補上 `base-branch.sh --derive` 與 `slugify.sh` 連叫兩次組多層分支名,`commit` 與 `pr` 兩段說明改寫成新行為。

Why:階梯與校準是這次的行為變更,README 是對外說明。說明沒跟上,使用者會照舊以為 base 可以自己挑、PR 要重開一支。

How:階梯表在 README 只寫一份摘要,唯一來源仍是 `jsc-meta` 的 `references/guidelines.md`。技能說明兩段各補上推導與校準兩件事,用詞與 SKILL.md 一致。

Who:讀 `jsc-git` 說明的人,以及要接 `base-branch.sh` 的其他 domain。
What:`plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json` 的 `version` 由 0.0.7 改為 0.0.8。

Why:本次改了 `base-branch.sh` 的介面與 `commit`、`pr` 兩支技能的步驟,屬於行為變更,版本要跟著往上走,各 CLI 才知道要更新。

How:三份只改 `version` 一個欄位,其餘內容不動,三份保持同一版號。

Who:`jsc-git` 外掛的套件描述檔。
Reviewed-on: #11
jiantw83 merged commit ad4414ab7d into develop 2026-08-27 03:39:40 +00:00
jiantw83 deleted branch feat/sdlc-flow-rules/main 2026-08-27 03:39:40 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: plugins/git#12